2012-07-30 26 views
2

對於每個不同的名稱,我想選擇具有最早的time_stamp(或UNIXTIME中的最小數字)的前三行。什麼是正確的查詢?SQL:爲每個不同的值選擇三行

開始表:

Name   Log-in Time 
--------  ----------------- 
Don   05:30:00 
Don   05:35:32 
Don   07:12:43 
Don   09:52:23 
Don   05:32:43 
James  03:30:00 
James  03:54:23 
James  09:51:54 
James  14:43:34 
James  43:22:11 
James  59:43:33 
James  20:12:11 
Mindy  05:32:22 
Mindy  15:14:44 
Caroline  10:02:22 
Rebecca  20:43:32 

末表:

Name   Log-in Time 
--------  ----------------- 
Don   05:30:00 
Don   05:35:32 
Don   07:12:43 
James  03:30:00 
James  03:54:23 
James  09:51:54 
Mindy  05:32:22 
Mindy  15:14:44 
Caroline  10:02:22 
Rebecca  20:43:32 
+2

您使用的是什麼RDBMS? – Taryn 2012-07-30 18:51:26

回答

3
WITH Table (Name, LoginTime, Row) AS 
(
    SELECT 
     Name, 
     LoginTime, 
     ROW_NUMBER() OVER (PARTITION BY Name ORDER BY LoginTime) 
    FROM SomeTable 
) 
SELECT 
    Name, 
    LoginTime 
FROM Table 
WHERE 
    Row <= 3 
+0

這適用於sql2008。 'SELECT Name,LoginTime FROM(SELECT Name,LoginTime,ROW_NUMBER()OVER(通過名稱ORDER BY LoginTime分隔)AS行FROM SomeTable)作爲WHERE行<= 3' – Muthukumar 2012-07-30 19:10:53

+1

它也可以在PostGres中運行,並基於快速谷歌,看來​​Oracle也支持CTE和Row_Number()函數。 編輯:Postgres和Oracle的最新版本,我應該說。 – Aushin 2012-07-30 19:17:57

+2

@Muthukumar:實際上,CTE是在SQL Server ** 2005 **中引入的 - 但它們也可用於其他RDBMS(它不是** Microsoft特定的擴展,而是最新的ANSI/ISO的一部分SQL標準) – 2012-07-30 19:20:28

0

ANSI標準的做法實際上看起來與以下工作:

http://www.sqlfiddle.com/#!2/b814d/15

SELECT 
    NAME 
    , LOGIN 
FROM (
    SELECT 
     test_first.NAME, 
     test_first.LOGIN, 
     COUNT(*) CNT 
    FROM 
     TABLE_NAME test_first 
    LEFT OUTER JOIN 
     TABLE_NAME test_second 
     ON (test_first.NAME = test_second.NAME) 
    WHERE 
     test_first.LOGIN <= test_second.LOGIN 
    GROUP BY 
     test_first.NAME, test_first.LOGIN) test_order 
WHERE 
    test_order.CNT <= 3 
ORDER BY 
    NAME ASC, LOGIN ASC