2010-08-28 58 views
7

Tôi có một bảng có tên là order có chứa các cột id, user_id, priceitem_id. Giá mặt hàng không cố định và tôi muốn chọn thứ tự đắt nhất của từng mặt hàng. Tôi muốn chọn user_id, item_idprice trong cùng một truy vấn. Tôi đã thử truy vấn sau nhưng nó không trả lại tập kết quả chính xác.Chọn nhiều giá trị tối đa

SELECT user_id, item_id, MAX(price) 
FROM order 
GROUP BY item_id 

Một số hàng trả về bởi truy vấn này có sai user_id. Tuy nhiên, tất cả các hàng trong tập kết quả đều hiển thị giá cao nhất chính xác của từng mặt hàng.

Trả lời

9

Bạn có thể muốn sử dụng một bảng có nguồn gốc như sau:

SELECT o1.item_id, o1.max_price, o2.user_id user_of_max_price 
FROM  (
      SELECT item_id, MAX(price) max_price 
      FROM `order` 
      GROUP BY item_id 
     ) o1 
JOIN  `order` o2 ON (o2.price = o1.max_price AND o2.item_id = o1.item_id) 
GROUP BY o1.item_id; 

Kiểm tra trường hợp:

CREATE TABLE `order` (user_id int, item_id int, price decimal(5,2)); 

INSERT INTO `order` VALUES (1, 1, 10); 
INSERT INTO `order` VALUES (1, 2, 15); 
INSERT INTO `order` VALUES (1, 3, 8); 
INSERT INTO `order` VALUES (2, 1, 20); 
INSERT INTO `order` VALUES (2, 2, 6); 
INSERT INTO `order` VALUES (2, 3, 15); 
INSERT INTO `order` VALUES (3, 1, 18); 
INSERT INTO `order` VALUES (3, 2, 13); 
INSERT INTO `order` VALUES (3, 3, 10); 

Kết quả:

+---------+-----------+-------------------+ 
| item_id | max_price | user_of_max_price | 
+---------+-----------+-------------------+ 
|  1 |  20.00 |     2 | 
|  2 |  15.00 |     1 | 
|  3 |  15.00 |     2 | 
+---------+-----------+-------------------+ 
3 rows in set (0.00 sec) 
+0

Nó hoạt động hoàn hảo. Cảm ơn, Daniel! – Ohas

1

Truy vấn của bạn nhóm các hàng theo item_id. Nếu bạn có nhiều mục với item_id 1, với số khác nhau là user_id, nó sẽ chỉ chọn user_id đầu tiên, không phải là user_id với giá cao nhất.

+0

Vâng, đúng vậy. Vậy làm thế nào để tôi đạt được những gì tôi đang cố gắng làm ở đây? Tôi đang cố gắng tìm ra ai đã mua món hàng ở mức giá cao nhất và giá đó là bao nhiêu. – Ohas

0

Bạn cần phải nhóm theo item_id AND user_id (hiển thị giá tối đa cho mỗi mục cho mỗi người dùng) hoặc nếu bạn chỉ muốn mục trong nhóm bạn cần phải suy nghĩ lại cột user_id. ví dụ: hiển thị giá tối đa cho một mặt hàng và hiển thị người dùng LAST đã thực hiện thay đổi về giá, HOẶC hiển thị giá Tối đa cho một mặt hàng và hiển thị cho người dùng MADE Giá tối đa cho mặt hàng đó. Hãy xem this post cho một số mẫu để làm điều này.

+0

Tôi không thể lấy mặt hàng, giá tối đa của nó và người dùng đã thực hiện mức giá đó trong một truy vấn? – Ohas

2

Trước tiên, bạn cần nhận giá tối đa cho mỗi id mục và sau đó quay lại order để nhận bản ghi có mục được đặt giá tối đa. Một cái gì đó giống như truy vấn sau đây sẽ làm việc. Mặc dù, nó sẽ trả về tất cả các bản ghi với giá mục tối đa.

SELECT user_id, item_id, price 
FROM order o 
JOIN (
     SELECT item_id, max(price) max_price 
     FROM order 
     GROUP BY item_id 
    ) o2 
    ON o.item_id = o2.item_id AND o.price = o2.max_price; 
2

Đây là một per- câu hỏi tối đa nhóm. Có various approaches cho vấn đề phổ biến này. Trên MySQL, thường nhanh hơn và đơn giản hơn để sử dụng tự tham gia rỗng hơn bất kỳ thứ gì liên quan đến truy vấn phụ:

SELECT o0.user_id, o0.item_id, o0.price 
FROM order AS o0 
LEFT JOIN order AS o1 ON o1.item_id=o0.item_id AND o1.price>o0.price 
WHERE o1.user_id IS NULL 

ie. "Chọn từng hàng không có hàng khác cho cùng một mặt hàng có giá cao hơn".

(Nếu hai hàng có mức giá tối đa cùng bạn sẽ nhận được cả hai quay trở lại. Chính xác những gì cần làm trong trường hợp của một tie là một vấn đề chung cho các giải pháp cho mỗi nhóm tối đa.)

+1

Không phải điểm chuẩn trong [liên kết bạn cung cấp] (http://kristiannielsen.livejournal.com/6745.html) cho thấy rằng bảng dẫn xuất (truy vấn con không tương quan) có nhanh hơn nhiều so với tự tham gia không? ... Tôi cũng từng nghĩ rằng việc tự tham gia vô ích là hơi nhanh hơn trong MySQL, và trên thực tế, tôi rất ngạc nhiên với các tiêu chuẩn đó. Tôi có một cảm giác tôi sẽ tự mình làm một số bài kiểm tra :) ... 1 anyway –

+1

Vâng, kết quả tất nhiên sẽ khác nhau tùy thuộc vào kích thước của bảng và chỉ mục liên quan. Tôi thường tìm thấy null-self-join nhanh nhất trên tập dữ liệu cụ thể của tôi trong quá khứ bằng cách sử dụng MySQL (có hỗ trợ subquery được biết là tương đối trẻ nên có lẽ không được tối ưu hóa như nó có thể). Thật thú vị khi điều tra thêm với một phiên bản MySQL gần đây. – bobince

1
SELECT user_id, item_id, MAX(price) 
FROM order 
GROUP BY item_id 

Các SQL bạn sử dụng là mâu thuẫn với GROUP. Khi bạn sử dụng GROUP, MYSQL sẽ luôn chọn user_id đầu tiên, nhưng giá cao nhất, đây là lý do tại sao người dùng sai nhưng giá là đúng.

Bạn có thể thử thêm ORDER BY price DESC để xem điều gì xảy ra nhưng tôi không thử trong môi trường của mình.

3

Có lẽ đây là lâu hơn một chút nhưng bạn có được trong khả năng đọc

SELECT 
     * 
FROM 
    `order` 
JOIN 
    (
     SELECT 
      item_id, 
      MAX(price) price 
     FROM 
      `order` 
     GROUP BY 
      item_id 
    ) 
    USING(item_id, price); 
0

nếu bạn muốn top 2 từ để thử này ...

nếu bạn muốn top 3 sau đó chỉ cần thay đổi điều kiện cuối cùng nơi item_rank in (1,2) ; đến where item_rank in (1,2,3) ;

select * from 
    (select item_id , price 
    , @curRow % @curNval as item_rank 
    , @curRow := @curRow + 1 AS row_number 
    from `order` , (SELECT @curRow := 1 , @curNval := 3) r 
    order by item_id , price desc ) tab where item_rank in (1,2) ; 
+0

có thể sử dụng làm item_rank> 2 hoặc item_rank> n – Kapil

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