2010-05-23 25 views
6

Xem xét bảng này (từ http://www.tizag.com/mysqlTutorial/mysqlmax.php):Làm thế nào để có được tất cả các trường của một hàng bằng hàm SQL MAX?

Id  name    type  price 
123451 Park's Great Hits Music 19.99 
123452 Silly Puddy  Toy  3.99 
123453 Playstation  Toy  89.95 
123454 Men's T-Shirt  Clothing 32.50 
123455 Blouse    Clothing 34.97 
123456 Electronica 2002 Music 3.99 
123457 Country Tunes  Music 21.55 
123458 Watermelon   Food  8.73 

truy vấn SQL này trả về item đắt nhất từ ​​mỗi loại: CHỌN loại, MAX (giá) TỪ sản phẩm GROUP BY loại

Clothing $34.97 
Food  $8.73 
Music $21.55 
Toy  $89.95 

tôi cũng muốn nhận được các trường idtên thuộc về giá tối đa trên, cho mỗi hàng. Truy vấn SQL nào sẽ trả về một bảng như thế này?

Id  name   type  price 
123455 Blouse   Clothing 34.97 
123458 Watermelon  Food  8.73 
123457 Country Tunes Music  21.55 
123453 Playstation  Toy  89.95 
+0

bạn có thể gắn thẻ câu hỏi của bạn một cách thích hợp cho các DBMS mà bạn đang sử dụng? –

+0

Có, tôi đã thêm Firebird 2.1 –

+0

Làm cách nào để xử lý mối quan hệ? Bạn có muốn chỉ một mục cho mỗi loại hoặc nhiều mục nếu có cà vạt đắt nhất? –

Trả lời

6

Đây là vấn đề greatest-n-per-group xuất hiện thường xuyên. theo cách thông thường của tôi giải quyết nó là một cách logic tương đương với câu trả lời được đưa ra bởi @ Martin Smith, nhưng không sử dụng một subquery:

SELECT T1.Id, T1.name, T1.type, T1.price 
FROM Table T1 
LEFT OUTER JOIN Table T2 
    ON (T1.type = T2.type AND T1.price < T2.price) 
WHERE T2.price IS NULL; 

Giải pháp của tôi và tất cả những người khác đưa ra trên chủ đề này cho đến nay có cơ hội sản xuất nhiều hàng cho mỗi giá trị của type, nếu có nhiều hơn một sản phẩm có cùng loại và cả hai đều có giá bằng nhau là giá trị tối đa. Có nhiều cách để giải quyết điều này và phá vỡ tie, nhưng bạn cần phải cho chúng tôi biết sản phẩm "thắng" trong trường hợp như thế.

Bạn cần một số thuộc tính khác được đảm bảo là duy nhất trên tất cả các hàng, ít nhất là đối với các hàng có cùng số type. Ví dụ, nếu sản phẩm có giá trị lớn hơn Id nên giành chiến thắng, bạn có thể giải quyết tie theo cách này:

SELECT T1.Id, T1.name, T1.type, T1.price 
FROM Table T1 
LEFT OUTER JOIN Table T2 
    ON (T1.type = T2.type AND (T1.price < T2.price 
     OR T1.price = T2.price AND T1.Id < T2.Id)) 
WHERE T2.price IS NULL; 
+0

Cảm ơn Bill, truy vấn thứ hai chính xác là những gì tôi đang tìm kiếm. Đó là một truy vấn nhỏ nhưng phức tạp đối với tôi. –

+0

cảm ơn vì đã tiếp tục trả lời câu hỏi này mỗi lần bật lên. Tôi quên làm thế nào để làm điều này mỗi 3 tháng hoặc lâu hơn và như giải pháp tự tham gia của bạn rất nhiều. – TMG

+0

@TMG: Bạn có thể thích cuốn sách sắp được phát hành của tôi, * SQL Antipatterns * [http://is.gd/b40bn]. Tôi có một chương về 'GROUP BY'. Bạn có thể đặt một dấu trang trên trang với giải pháp nối ngoài này! :-) –

6

Sửa Chỉ cần cập nhật tôi để đáp ứng yêu cầu làm rõ

SELECT Id, name, type,price 
FROM Table T1 
WHERE NOT EXISTS(
      SELECT * FROM TABLE T2 
      WHERE T1.type=t2.type 
      AND T2.Price >= T1.Price 
      AND T2.Id > T1.Id 
     ) 
+0

+1: Điều này sẽ hoạt động đối với bất kỳ phương ngữ SQL nào. :) – Simon

+0

+1 Ah vâng, tôi đã thực hiện nó như thế này trước đây, nhưng vì vậy sql chỉ một vài lần một năm, tôi awlays quên lớn hơn lừa để đảm bảo bạn đã có tối đa. – mdma

+0

Thật không may tôi không thể upvote trừ khi bạn chỉnh sửa câu trả lời của bạn ... sẽ thêm một không gian, xin vui lòng? :) – Simon

3

Bạn có thể làm điều đó với một subselect

SELECT id, name, type, price FROM products p1 
WHERE EXISTS (Select type, max(price) FROM Products p2 
       GROUP BY type 
       WHERE p1.type=p2.type AND p1.price=p2.MAX(price)) 

hoặc một bên tham gia

SELECT id, name, type, price FROM products p1 
INNER JOIN (Select type, max(price) FROM Products p2 GROUP BY type) maxPrice 
     ON maxPrice=price=p1.price AND maxPrice.type=p1.price 
+0

Cảm ơn mdma, nhưng nếu có nhiều mục có cùng giá tối đa và loại nó trả về cả hai, nhưng tôi chỉ cần một –

+0

Ok. Tôi thấy có một câu trả lời hay đã được chọn, vì vậy không cần cập nhật điều này. – mdma

Các vấn đề liên quan