我目前正在使用这个:
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 :(得分: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,min和join的子查询(apply很可能导致循环连接计划,而group by first和join after - to hash join)
3)为你的样本案例
SELECT O1.id, MIN(O1.UtcDateTime)
FROM #Temp AS O1
GROUP BY O1.id
4)小桌子;注意,row_number没有搜索,所以你是&#34;禁用&#34;所有索引并请求额外的内存来填充新列
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 :(得分:1)
您也可以按[UtcDateTime]使用ROW_NUMBER顺序,并按[SomeId]分区以获得第一次出现。
SELECT *
FROM (
SELECT *,
ROW_NUMBER () OVER (PARTITION BY SomeId ORDER BY [UtcDateTime]) RN
FROM #Temp
) t
WHERE Rn = 1
答案 2 :(得分:1)
你没有错,但你可以尝试这个(更简单的方法):
SELECT SomeId, MIN(UTCDateTime) AS UTCDateTime FROM #Temp GROUP BY SomeId
将为每个'SomeId'
捕获第一个匹配项答案 3 :(得分: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)