我有下表,其中*
标记列构成主键。它们基本上是划船距离(500,1000等)和以毫秒为单位的时间。
* user_id
* season
* n
date
meters
time
我需要为特定用户找到个人最佳用户,因此每个距离的最短时间和划分的日期。
我一直在试图解决这个问题,但是通过所有子查询,加入和分组,我只是......努力工作。有谁能帮助SQL newb吗?
我的最终解决方案基于已接受的答案。试图简化它有点,因为我事先知道它是谁的用户。还有一个条款可以选择标准距离。似乎我可以看到工作,但如果你看到任何可疑的东西,请告诉我!
SELECT
MIN(x.date) "date",
x.meters,
x.time
FROM session x
INNER JOIN (SELECT
z.date,
z.meters,
MIN(z.time) "time"
FROM session z
WHERE z.user_id = :user_id
AND z.meters IN (500,1000,2000,5000,6000,10000,21097,42195,100000)
GROUP BY z.meters) y
ON x.meters = y.meters AND x.time = y.time
GROUP BY x.meters, x.time
答案 0 :(得分:1)
好的,试试这个。
(1)
SELECT x.date, x.user_id, x.meters, x.time
FROM
MyTable x
JOIN
(
SELECT y.user_id, y.meters, min(y.time) AS time
FROM
MyTable y
GROUP BY y.user_id, y.meters
) t ON x.user_id = t.user_id AND x.time = t.time AND x.meters = t.meters
这是某种模式, 我经常看到它被DBA使用过。
但是上面的这个将为每个用户提供每行距离> = 2行
(如果用户不止一次达到最佳时间)。
如果你想要,例如他达到目的的第一个日期
最好的结果然后你可以尝试下面的第二个查询
在(2)中,查询(1)基本上用作子查询。
(2)
SELECT min(m.date), m.user_id, m.meters, m.time
FROM
(
SELECT x.date, x.user_id, x.meters, x.time
FROM
MyTable x
JOIN
(
SELECT y.user_id, y.meters, min(y.time) AS time
FROM
MyTable y
GROUP BY y.user_id, y.meters
) t ON x.user_id = t.user_id AND x.time = t.time AND x.meters = t.meters
) m
GROUP BY m.user_id, m.meters, m.time
好的,现在我测试了两个查询。
所以现在我很放松,因为我确实没有说谎 给你:)用两个查询中的任何一个。
(2)的简化版(对于特定用户)将是这个。
(3)
SELECT min(x.date), x.user_id, x.meters, x.time
FROM
MyTable x
JOIN
(
SELECT y.user_id, y.meters, min(y.time) AS time
FROM
MyTable y
where y.user_id = 1
GROUP BY y.user_id, y.meters
) t ON x.user_id = t.user_id AND x.time = t.time AND x.meters = t.meters
GROUP BY x.user_id, x.meters, x.time
(4)
以下是我测试查询的架构和数据。
create table MyTable(user_id int, season int, n int, date datetime, meters int, time int);
insert into MyTable values (1, 1, 10, '2010-01-08', 500, 10);
insert into MyTable values (1, 1, 20, '2010-01-10', 500, 10);
insert into MyTable values (1, 1, 30, '2010-01-10', 1000, 50);
insert into MyTable values (1, 1, 40, '2010-02-10', 1000, 50);
insert into MyTable values (1, 1, 50, '2010-03-10', 1000, 70);
insert into MyTable values (1, 1, 60, '2010-03-10', 5000, 20);
insert into MyTable values (1, 1, 70, '2010-04-10', 5000, 20);
insert into MyTable values (1, 1, 80, '2010-05-10', 5000, 50);
insert into MyTable values (2, 1, 90, '2010-01-10', 500, 10);
insert into MyTable values (2, 1, 100, '2010-01-08', 500, 10);
insert into MyTable values (2, 1, 110, '2010-01-11', 1000, 50);
insert into MyTable values (2, 1, 120, '2010-02-11', 1000, 50);
insert into MyTable values (2, 1, 130, '2010-03-11', 1000, 70);
insert into MyTable values (2, 1, 140, '2010-05-11', 5000, 20);
insert into MyTable values (2, 1, 150, '2010-06-11', 5000, 20);
insert into MyTable values (2, 1, 160, '2010-07-11', 5000, 50);