2016-03-15 51 views
1

我目前使用這個最早條目的IDS:相關子查詢來選擇

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL DROP TABLE #Temp 

CREATE TABLE #Temp 
(
    SomeId INT, 
    UtcDateTime DATETIME2 
) 

INSERT INTO #Temp 
    SELECT 1, DATETIME2FROMPARTS(2015,1,1,1,1,1,0,0) 
     UNION 
    SELECT 1, DATETIME2FROMPARTS(2015,1,1,2,1,1,0,0) 
     UNION 
    SELECT 2, DATETIME2FROMPARTS(2015,1,1,3,1,1,0,0) 
     UNION 
    SELECT 2, DATETIME2FROMPARTS(2015,1,12,4,1,1,0,0) 
     UNION 
    SELECT 2, DATETIME2FROMPARTS(2015,1,12,5,1,1,0,0) 
     UNION 
    SELECT 3, DATETIME2FROMPARTS(2015,1,12,5,1,1,0,0) 

SELECT * FROM #Temp ORDER BY UtcDateTime ASC 

SELECT 
    * 
FROM #Temp AS O1 
WHERE UtcDateTime = 
(
    SELECT MIN(UtcDateTime) FROM #Temp AS O2 WHERE O1.SomeId = O2.SomeId 
) 
AND SomeId = 
(
    SELECT MAX(SomeId) FROM #Temp AS O2 WHERE O1.SomeId = O2.SomeId AND O1.UtcDateTime = O2.UtcDateTime 
) 

的意圖是選擇用於基於UtcDateTime鮮明SomeId每個條目的第一個匹配。換句話說,我在這些行之後:

SomeId UtcDateTime 
1 2015-01-01 01:01:01.0000000 
2 2015-01-01 03:01:01.0000000 
3 2015-01-12 05:01:01.0000000 

以上相關的子查詢方法是否正確?

+0

爲什麼不選擇SomeId,MIN(UtcDateTime )FROM #temp GROUP BY SomeId? –

回答

1

您也可以使用[UtcDateTime] ROW_NUMBER秩序,[SomeId]劃分拿到第一發生。

SELECT * 
FROM (
      SELECT *, 
        ROW_NUMBER() OVER (PARTITION BY SomeId ORDER BY [UtcDateTime]) RN 
      FROM #Temp 
     ) t 
WHERE Rn = 1 
0

選擇那裏有長着相同的ID沒有行和較早時間戳行:

SELECT SomeId, UtcDateTime 
FROM Temp AS T1 
WHERE NOT EXIST (
    SELECT 1 FROM Temp AS T2 
    WHERE T1.SomeId = T2.SomeId 
    AND T2.UtcDateTime < T1.UtcDateTime) 
3

兩個自連接(提到三次同桌) - 在我看來太

1)

SELECT * 
FROM #Temp AS O1 
WHERE not exists 
    (select 1 from #Temp O2 
     where O2.SomeId = O1.SomeId and O2.UtcDateTime < O1.UtcDateTime) 

2)

SELECT * 
FROM #Temp AS O1 
CROSS APPLY 
(
    SELECT TOP 1 O2.UtcDateTime 
    FROM #Temp as O2 
    WHERE O2.SomeId = O1.SomeId 
    ORDER BY O2.UtcDateTime ASC 
) O2 
WHERE O1.UtcDateTime = O2.UtcDateTime 

2.1),子查詢與GROUP BY,分鐘,加入(申請很可能導致與循環聯接計劃,同時通過第一組和加入後 - 以哈希連接)

3)爲您的樣品情況下

SELECT O1.id, MIN(O1.UtcDateTime) 
FROM #Temp AS O1 
GROUP BY O1.id 

4)小桌子;注意,ROW_NUMBER是不是搜索,這樣你就「禁用」的所有索引和請求更多的內存來填充新列

SELECT * 
FROM 
(
    SELECT O1.*, 
    ROW_NUMBER() OVER(PARTITION BY O1.SomeID ORDER BY O1.UtcDateTime) as row_no 
    FROM #Temp as O1 
) O2 
WHERE O2.row_no = 1 
1

你們是沒有錯的,但你可以試試這個(更簡單的方法):

SELECT SomeId, MIN(UTCDateTime) AS UTCDateTime FROM #Temp GROUP BY SomeId 

第一次出現將捕獲每個 'SomeId'