2013-12-15 37 views
0

我有下表,其中*標記列組成主鍵。他們基本上是以劃分的距離(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

這裏「ON x.meters = y.meters AND x.time = y.time」,我想你可能會遇到問題,因爲x.user_id可能是<> y.user_id。將此添加到您的聯接中:「AND x.user_id = y.user_id」另外,我更新了我的答案,您可能會使用我的測試數據,我試圖使數據變得一般和令人討厭,足以涵蓋大多數情況。不知道爲什麼這些SQL小提琴鏈接到期。我仍然不熟悉sql小提琴。我會說只是從我的查詢中使用(3),並添加標準距離過濾器,如果你願意。 –

+0

但是,當我僅選擇具有單個user_id的行時,爲什麼user_id會有所不同? – Svish

+1

您在內部聯接之後,在y中選擇單個用戶。但是你在x中有什麼?想象一下,如果x.user_id不同,但該傢伙的米和相同的時間與y.user_id。您將加入他們,您將選擇x的最小(日期)。我不明白,聽起來像是一個bug。試試我的測試數據。順便說一句,我現在會離線,對不起。再次,僅僅使用(3)我建議,很簡單。 –

回答

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 

OK,現在我測試這兩個查詢。

所以現在我很放鬆,因爲我確實沒有說謊 給你:)與任何兩個查詢。 (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); 
+0

啊,忘了我也需要日期,這是什麼讓我出差。 – Svish

+0

也很簡單,但需要一些時間。 –

+0

任何幫助,高度讚賞! – Svish