2012-10-15 11 views
45

SELECT name, price, photo FROM drinks, drinks_photos WHERE drinks.id = drinks_idCHỌN * TỪ nhiều bảng. MySQL

yeilds 5 hàng (5 mảng), photo là trường duy nhất liên tiếp. name, price được lặp lại (tại đây,fanta-name, pricelặp lại 3 lần.) Làm cách nào để loại bỏ các bản sao này?

Chỉnh sửa: Tôi muốn name, price và tất cả photo cho mỗi đồ uống.

id  name  price 
    1. fanta  5 
    2.  dew   4 


id  photo     drinks_id 
    1.  ./images/fanta-1.jpg  1 
    2.  ./images/fanta-2.jpg  1 
    3.  ./images/fanta-3.jpg  1 
    4.  ./images/dew-1.jpg  2 
    5.  ./images/dew-2.jpg  2 
+4

Bạn cũng có 5 hàng phù hợp, vì bạn có một số hàng có cùng đồ uống_id. Bạn sẽ mong đợi điều gì sẽ xảy ra? Bạn muốn giữ ảnh nào? –

Trả lời

66

Điều bạn làm ở đây được gọi là JOIN (mặc dù bạn làm điều này hoàn toàn vì bạn chọn từ nhiều bảng). Điều này có nghĩa là nếu bạn không đặt bất kỳ điều kiện nào trong mệnh đề WHERE của mình, bạn có tất cả các kết hợp trong các bảng đó. Chỉ với điều kiện của bạn, bạn hạn chế tham gia của bạn với những hàng nơi id uống phù hợp.

Nhưng vẫn còn X nhiều hàng trong kết quả cho mỗi đồ uống, nếu có X ảnh với drink_id cụ thể này. Tuyên bố của bạn không giới hạn trong đó ảnh bạn muốn có!

Nếu bạn chỉ muốn một hàng cho mỗi đồ uống, bạn phải nói cho SQL biết bạn muốn làm gì nếu có nhiều hàng với một graphics_id cụ thể. Đối với điều này, bạn cần nhóm và aggregate function. Bạn cho SQL biết các mục mà bạn muốn nhóm lại với nhau (ví dụ tất cả các đối tượng đồ uống bằng nhau) và trong SELECT, bạn phải cho biết các mục riêng biệt nào cho mỗi hàng kết quả được nhóm sẽ được thực hiện. Đối với các con số, điều này có thể là trung bình, tối thiểu, tối đa (để đặt tên cho một số).

Trong trường hợp của bạn, tôi không thể thấy ý nghĩa khi truy vấn ảnh cho đồ uống nếu bạn chỉ muốn một hàng. Bạn có thể nghĩ rằng bạn có thể có một mảng ảnh trong kết quả của mình cho mỗi đồ uống, nhưng SQL không thể làm điều này. Nếu bạn chỉ muốn bất kỳ ảnh và bạn không quan tâm mà bạn sẽ nhận được, chỉ cần nhóm bởi drinks_id (theo thứ tự để có được chỉ có một hàng cho mỗi thức uống):

SELECT name, price, photo 
FROM drinks, drinks_photos 
WHERE drinks.id = drinks_id 
GROUP BY drinks_id 

name  price photo 
fanta 5  ./images/fanta-1.jpg 
dew  4  ./images/dew-1.jpg 

Trong MySQL, chúng tôi cũng có GROUP_CONCAT, nếu bạn muốn tên tập tin để được nối với một chuỗi duy nhất:

SELECT name, price, GROUP_CONCAT(photo, ',') 
FROM drinks, drinks_photos 
WHERE drinks.id = drinks_id 
GROUP BY drinks_id 

name  price photo 
fanta 5  ./images/fanta-1.jpg,./images/fanta-2.jpg,./images/fanta-3.jpg 
dew  4  ./images/dew-1.jpg,./images/dew-2.jpg 

Tuy nhiên, điều này có thể nguy hiểm nếu bạn có , trong các giá trị trường, vì rất có thể bạn muốn chia nhỏ lại điều này ở phía máy khách. Nó cũng không phải là một hàm tổng hợp SQL chuẩn.

+0

Yea tôi muốn tên, giá cả và một loạt các hình ảnh cho mỗi thức uống. – NestedWeb

+1

Mảng hình ảnh ... bạn có thực sự biết cơ sở dữ liệu relatinal là gì không? –

+2

Ngôn ngữ nào bạn viết chương trình của mình để thực hiện các truy vấn đó? Bởi vì MySQL không hỗ trợ các mảng như các kiểu trường. Bạn phải thực hiện một số thủ thuật chuỗi như với 'GROUP_CONCAT' và chia nhỏ nó một lần nữa. Một bình thường không làm điều này trong cơ sở dữ liệu quan hệ. Bạn nên làm việc nhóm trong chương trình, không phải trong SQL (phát hiện các ID trùng lặp và xây dựng các mảng đó trong chương trình của bạn). – leemes

0

Để loại bỏ các bản sao, bạn có thể nhóm theo drinks.id. Nhưng theo cách đó, bạn sẽ chỉ nhận được một ảnh cho mỗi drinks.id (ảnh bạn sẽ nhận được phụ thuộc vào việc triển khai nội bộ cơ sở dữ liệu).

Mặc dù nó không được ghi lại, trong trường hợp của MySQL, bạn sẽ nhận được ảnh với mức thấp nhất id (theo kinh nghiệm của tôi, tôi chưa bao giờ thấy hành vi khác).

SELECT name, price, photo 
FROM drinks, drinks_photos 
WHERE drinks.id = drinks_id 
GROUP BY drinks.id 
+1

Bạn nên nhóm theo id. Luôn nhóm theo trường duy nhất của bạn để nhận các hàng riêng biệt của bảng nguồn. Trong trường hợp của bạn, nếu hai loại đồ uống có cùng tên (nhưng có các hàng khác nhau trong bảng), bạn cũng sẽ nhóm chúng lại với nhau. – leemes

+0

cảm ơn bạn leemes, tôi đã không nhận thấy rằng có trường id duy nhất. Tôi đã chỉnh sửa câu trả lời của mình. Tất nhiên sử dụng id của nó tốt hơn. @ypercube, bạn có thực sự nghĩ rằng, nhận xét của bạn bổ sung thêm một cái gì đó bình thường để đăng bài? – bhovhannes

+0

@bhovhannes: Không, bạn đúng, xin lỗi. Lời bình luận không thêm bất cứ điều gì hữu ích. Câu trả lời đúng là tốt hơn - mặc dù tôi vẫn không đồng ý với việc sử dụng 'GROUP BY' (không phải là tiêu chuẩn SQL) mà không giải thích lý do tại sao nó hoạt động và cách nó sẽ trả về một ảnh' bán ngẫu nhiên 'cho mọi thức uống. (Các * "đầu tiên" * trong * "bạn sẽ nhận được hình ảnh đầu tiên" * cụm từ chỉ là sai). –

2

Bạn sẽ có giá trị trùng lặp cho tên và giá tại đây. Và id là trùng lặp trong bảng drinks_photos.There là không có cách nào bạn có thể tránh them.Also chính xác những gì bạn muốn đầu ra?