我有一个查询,其中我为给定的事件返回多行,例如:
ID | DateTime | String
1017436 | 2013-09-13 05:19:20.000 | Hello
1017436 | 2013-09-13 11:49:00.000 | World
我希望结果只包含任何给定ID的行的
我最初认为这样的查询就是答案:
; WITH cte AS
( SELECT *,
rn = ROW_NUMBER() OVER (PARTITION BY ixBug ORDER BY dt)
FROM dbo.BugEvent
)
SELECT ixBug, dt, s
FROM cte
WHERE
ixBug IN (SELECT Bug.ixBug
FROM
dbo.Bug
JOIN
dbo.Mailbox ON Mailbox.ixMailbox = Bug.ixMailbox
WHERE
ixBug = '1017436'
AND
YEAR(dtOpened) >= '2013'
AND
MONTH(dtOpened) = '09'
AND
sOriginalTitle NOT LIKE '\[web\]%' ESCAPE '\'
AND
dbo.Bug.ixProject = (SELECT ixProject
FROM dbo.Project
WHERE sProject = 'Support')
AND
dbo.Bug.ixCategory = (SELECT ixCategory
FROM dbo.Category
WHERE sCategory = '.inquiry')
AND
Bug.ixBug NOT IN(SELECT Bug.ixBug
FROM
dbo.Bug
JOIN
dbo.Mailbox ON Mailbox.ixMailbox = Bug.ixMailbox
WHERE
YEAR(dtOpened) >= '2013'
AND
MONTH(dtOpened) <= '09'
AND
sOriginalTitle LIKE '\[web\]%' ESCAPE '\'
AND
dbo.Bug.ixProject = (SELECT ixProject
FROM dbo.Project
WHERE sProject = 'Support')
AND
dbo.Bug.ixCategory = (SELECT ixCategory
FROM dbo.Category
WHERE sCategory = '.inquiry')))
AND
sVerb = 'Incoming Email';
但是,由于某种原因,结果会保留两行。
答案 0 :(得分:3)
您可以使用窗口函数ROW_NUMBER()
或MIN()
。我们的想法是按ID分配行 - OVER (PARTITION BY id)
- 然后分配行号(按日期时间排序)或查找每个ID的最小日期时间。
ROW_NUMBER()
的解决方案:
; WITH cte AS
( SELECT id, datetime, string,
rn = ROW_NUMBER() OVER (PARTITION BY id ORDER BY datetime)
FROM tableX
)
SELECT id, datetime, string
FROM cte
WHERE rn = 1 ;
和MIN()
:
; WITH cte AS
( SELECT id, datetime, string,
min_datetime = MIN(datetime) OVER (PARTITION BY id)
FROM tableX
)
SELECT id, datetime, string
FROM cte
WHERE datetime = min_datetime ;
第二个版本的行为略有不同。如果有两个(或更多)行具有完全相同的ID日期时间,则它们将同时出现在结果中。
答案 1 :(得分:1)
您可以使用ROW_NUMBER()
生成可以过滤的序号。
SELECT ID, DateTime, String
FROM
(
SELECT ID, DateTime, String,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DateTime) RN
FROM tableName
) a
WHERE RN = 1
答案 2 :(得分:1)
在公用表表达式CTE中选择每个ID的最小日期,然后再加入它。
with minDates (id, date)
as
(
select id, min(date) as date from YourTable
group by id
)
select yt.*
from YourTable yt
inner join minDates md on yt.id = md.id and yt.date = md.date
答案 3 :(得分:1)
select top 1 id, date_time, string
from table
where id = ?
order by date_time
答案 4 :(得分:0)
Select
ID
, DateTime
, String
From MyTable t1
Where t1.DateTime =
(
Select Min(t2.DateTime)
From MyTable t2
Where td.ID = t1.ID
)
使用子查询获取每个ID组的最小日期时间,然后使用该子查询来限定您提取的ID。如果是平局,你会得到两者。如果ID是按时间顺序排列的,则可以通过使用ID而不是DateTime作为选择器来避免这种情况。