MySQL - Chọn dữ liệu từ nhiều bảng có cùng cấu trúc nhưng dữ liệu khác nhau


79

Ok, đây là tình huống khó xử của tôi, tôi có một cơ sở dữ liệu được thiết lập với khoảng 5 bảng, tất cả đều có cùng cấu trúc dữ liệu. Dữ liệu được phân tách theo cách này cho các mục đích bản địa hóa và để chia ra tổng cộng khoảng 4,5 triệu bản ghi.

Phần lớn thời gian chỉ cần một bàn và tất cả đều ổn. Tuy nhiên, đôi khi dữ liệu cần thiết từ 2 hoặc nhiều bảng và nó cần được sắp xếp theo cột do người dùng xác định. Đây là nơi tôi đang gặp vấn đề.

cột dữ liệu:

id, band_name, song_name, album_name, genre

Trạng thái MySQL:

SELECT * from us_music, de_music where `genre` = 'punk'

MySQL đưa ra lỗi này:

#1052 - Column 'genre' in where clause is ambiguous

Rõ ràng, tôi đang làm điều này sai. Có ai muốn làm sáng tỏ điều này cho tôi không?

Câu trả lời:


177

Tôi nghĩ bạn đang tìm mệnh đề UNION , a la

(SELECT * from us_music where `genre` = 'punk')
UNION
(SELECT * from de_music where `genre` = 'punk')

@ mihai-limban - xin lỗi đã làm phiền bạn, nhưng có cách nào để nhận ra từ tập kết quả rằng "kết quả đến từ bảng nào". Beacuse, nếu chúng ta cần cập nhật / xóa một bản ghi từ tập kết quả này, không có cách nào để biết.
web-nomad

7
@Pushpesh thêm một định danh duy nhất cho mỗi chuỗi SELECT, ví dụ như:(SELECT 'us_music' AS from_table, * FROM us_music WHERE genre = 'punk') UNION ...
jkrcma

Giá trị của thể loại là gì không rõ nhưng id phải khớp trong hai bảng? Bạn có thể làm một cái gì đó như thế này? (SELECT 1) AS select1 UNION (SELECT 2) AS select2 WHERE select1.id=select2.id
ZurabWeb

Hoàn hảo, chính xác tại sao tôi yêu Stack! Google, tìm câu hỏi và câu trả lời ngăn xếp đã có ở đây! Cảm ơn!
Rocco The Taco

Cú pháp để nhóm theo UNION của tập kết quả và sau đó cũng thực hiện thứ tự theo? Giả sử nó viewCountmovieTitlenơi có một DB cho mỗi tháng. Bạn kết hợp tất cả 12 bảng với nhau là tốt nhưng sau đó bạn nhận được 12 bộ kết quả riêng lẻ trong đầu ra. Điều gì sẽ xảy ra nếu bạn chỉ muốn một tập hợp kết quả trong đó tất cả các kết quả được nhóm theo movieTitleviewCountgiá trị được tổng hợp cho mỗi movieTitlehàng?
anon58192932

19

Có vẻ như bạn sẽ hạnh phúc hơn với một chiếc bàn. Năm có cùng một lược đồ, và đôi khi cần được trình bày như thể chúng đến từ một điểm để đặt tất cả vào một bảng.

Thêm một cột mới có thể được sử dụng để phân biệt giữa năm ngôn ngữ (tôi cho rằng đó là ngôn ngữ khác nhau giữa các bảng vì bạn đã nói nó là ngôn ngữ để bản địa hóa). Đừng lo lắng về việc có 4,5 triệu bản ghi. Bất kỳ cơ sở dữ liệu thực có thể xử lý kích thước đó không có vấn đề. Thêm các chỉ mục chính xác và bạn sẽ không gặp khó khăn gì khi xử lý chúng như một bảng duy nhất.


Tôi ban đầu có tất cả dữ liệu của mình trong một bảng duy nhất, nhưng nó bắt đầu thu thập dữ liệu trong 5-10 giây sau khoảng 3,5 triệu bản ghi. tôi thấy việc chia nhỏ nó ra phù hợp nhất với tôi vì nó nhanh hơn nhiều. tôi có một webhost mới bây giờ, vì vậy nó có thể tốt hơn, nhưng có vẻ như quá nhiều rắc rối một để kết hợp nó
Jayrox

26
Có vẻ như bạn cần thêm chỉ mục vào các bảng.
Ned Batchelder

1
Có, về cơ bản bạn đã điều trị một triệu chứng của sự cố mà không giải quyết được vấn đề cốt lõi (lập chỉ mục không đúng / không đủ). Điều gì sẽ xảy ra tiếp theo nếu một trong 5 bảng của bạn đạt đến 4,5 triệu hàng và bắt đầu thu thập thông tin lại?
Lo-Tan

5

Bất kỳ câu trả lời nào ở trên đều hợp lệ hoặc một cách khác là mở rộng tên bảng để bao gồm cả tên cơ sở dữ liệu - ví dụ:

SELECT * from us_music, de_music where `us_music.genre` = 'punk' AND `de_music.genre` = 'punk'

cung cấp cho bạn một tập kết quả rất khó xác định: tất cả các cặp us_ và de_ punk có thể có.
David Schmitt,

4

Cột này không rõ ràng vì nó xuất hiện trong cả hai bảng, bạn sẽ cần chỉ định trường where (hoặc sắp xếp) đầy đủ, chẳng hạn như us_music.genre hoặc de_music.genre nhưng bạn thường chỉ định hai bảng nếu sau đó bạn muốn nối chúng lại với nhau trong một số thời trang. Cấu trúc mà bạn đang xử lý đôi khi được gọi là bảng được phân vùng mặc dù nó thường được thực hiện để tách tập dữ liệu thành các tệp riêng biệt thay vì chỉ tách tập dữ liệu một cách tùy ý. Nếu bạn chịu trách nhiệm về cấu trúc cơ sở dữ liệu và không có lý do chính đáng để phân vùng dữ liệu thì tôi sẽ tạo một bảng lớn với trường "origin" bổ sung có chứa mã quốc gia nhưng có thể bạn đang làm điều đó vì lý do hiệu suất hợp pháp . Sử dụng liên hợp để tham gia các bảng bạn quan tâm http: //dev.mysql.hoặc bằng cách sử dụng công cụ cơ sở dữ liệu Hợp nhất http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html .


3

Nỗ lực ban đầu của bạn để mở rộng cả hai bảng sẽ tạo ra một JOIN ngầm. Điều này được hầu hết các lập trình viên SQL có kinh nghiệm phản đối vì nó phân tách các bảng được kết hợp với điều kiện như thế nào.

Đây UNIONlà một giải pháp tốt cho các bảng như hiện tại, nhưng không có lý do gì chúng không thể được đưa vào một bảng với việc lập chỉ mục tốt. Tôi đã thấy việc thêm chỉ mục chính xác vào một bảng lớn làm tăng tốc độ truy vấn lên ba bậc.


3

Câu unionlệnh gây ra thời gian giao dịch trong dữ liệu khổng lồ. Tốt nhất là thực hiện lựa chọn trong 2 bước:

  1. chọn id
  2. sau đó chọn bảng chính với nó
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.