2016-03-15 59 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'