[英]mysql: group by ID, get highest priority per each ID
我有以下mysql表名為“pics”,包含以下字段和示例數據:
id vehicle_id filename priority
1 45 a.jpg 4
2 45 b.jpg 1
3 56 f.jpg 4
4 67 cc.jpg 4
5 45 kt.jpg 3
6 67 gg.jpg 1
在單個查詢中,是否可以為每個vehicle_id獲取一行,並且該行是最高優先級?
我正在尋找的結果:
array (
[0] => array( [id] => '2', [vehicle_id] => '45', [filename] => 'b.jpg', [priority] => '1' ),
[1] => array( [id] => '3', [vehicle_id] => '56', [filename] => 'f.jpg', [priority] => '4' ),
[2] => array( [id] => '6', [vehicle_id] => '67', [filename] => 'gg.jpg', [priority] => '1' )
);
如果在單個查詢中不可能,那么最好的方法是什么?
謝謝!
這似乎是每組查詢的典型最大值。 在大多數數據庫中,您可以使用ROW_NUMBER輕松完成此操作:
SELECT id, vehicle_id, filename, priority
FROM (
SELECT
id, vehicle_id, filename, priority,
ROW_NUMBER() OVER (PARTITION BY vehicle_id
ORDER BY priority DESC, id) AS rn
FROM pics
) AS T1
WHERE rn = 1
由於MySQL尚不支持ROW_NUMBER,您可以使用變量來模擬它:
SELECT id, vehicle_id, filename, priority
FROM (
SELECT
id, vehicle_id, filename, priority,
@rn := CASE WHEN @prev_vehicle_id = vehicle_id
THEN @rn + 1
ELSE 1
END AS rn,
@prev_vehicle_id := vehicle_id
FROM (SELECT @prev_vehicle_id := NULL) vars, pics T1
ORDER BY vehicle_id, priority DESC, id
) T2
WHERE rn = 1
請注意,在明確表示需要處理優先級關系之前,已發布此方法。 我將它留在這里供參考(見下面的評論)。 查看@ Mark的答案 ,找出可根據需要處理關系的解決方案:
SELECT p.id, p.vehicle_id, p.filename, p.priority
FROM pics p
JOIN (
SELECT vehicle_id, MAX(priority) max_priority
FROM pics
GROUP BY vehicle_id
) sub_p ON (sub_p.vehicle_id = p.vehicle_id AND
sub_p.max_priority = p.priority)
GROUP BY p.vehicle_id;
這假設同一vehicle_id
不存在優先級關系。
測試用例:
CREATE TABLE pics (id int, vehicle_id int, filename varchar(10), priority int);
INSERT INTO pics VALUES ('1', '45', 'a.jpg', '4');
INSERT INTO pics VALUES ('2', '45', 'b.jpg', '1');
INSERT INTO pics VALUES ('3', '56', 'f.jpg', '4');
INSERT INTO pics VALUES ('4', '67', 'cc.jpg', '4');
INSERT INTO pics VALUES ('5', '45', 'kt.jpg', '3');
INSERT INTO pics VALUES ('6', '67', 'gg.jpg', '1');
結果:
+------+------------+----------+----------+
| id | vehicle_id | filename | priority |
+------+------------+----------+----------+
| 1 | 45 | a.jpg | 4 |
| 3 | 56 | f.jpg | 4 |
| 4 | 67 | cc.jpg | 4 |
+------+------------+----------+----------+
3 rows in set (0.01 sec)
雖然這可能是“被接受”的答案,但Mark的解決方案在正常情況下的性能要好很多倍,而且對於這個問題同樣有效,所以無論如何都要在生產中找到他的解決方案!
SELECT a.id, a.vehicle_id, a.filename, a.priority
FROM pics a
LEFT JOIN pics b -- JOIN for priority
ON b.vehicle_id = a.vehicle_id
AND b.priority > a.priority
LEFT JOIN pics c -- JOIN for priority ties
ON c.vehicle_id = a.vehicle_id
AND c.priority = a.priority
AND c.id < a.id
WHERE b.id IS NULL AND c.id IS NULL
假設'id'是一個不可為空的列。
[編輯]:我的不好,需要第二次加入,不能只用一次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.