我有一张这样的桌子:
对于每个TaskConfigId,都有一个TaskGuid。如果相同的TaskConfigId的TaskGuid相同,则似乎它们适用于相同的Task。通常,TaskStatusId将为10或20。发生某些情况时,TaskStatusId将为其他值,即15。但是对于每个任务,它始终具有10和20。
因此,如果任务的状态为10 AND 20,则表示没有特别的事情发生。
现在,我想查找一个TaskConfigId(例如100),它是最后一个CreatedDate的时间,并且它只有TaskStatusId 10和20,没有其他值。因此,如果TaskConfigId为40,则突出显示的大小写不正确。
这就是我所拥有的
SELECT TOP (1) CreatedDate
FROM [aptfeed].[TaskTracking]
WHERE TaskGuid IN (
SELECT TaskGuid
FROM [aptfeed].[TaskTracking]
WHERE TaskConfigId = 100
GROUP BY TaskGuid HAVING COUNT(*) = 2
)
AND TaskStatusId = 10 -- start
ORDER BY CreatedDate DESC
基本上,它将TaskGuid分组为TaskConfigId,并确保它具有2个条目。对其进行排序,然后得到最后一个。
我的问题是:如果我想确保2个条目分别为10和20(如果我们可以确保顺序先是10,然后是20,则更好)怎么办?
我尝试过:
SELECT TOP (1) CreatedDate
FROM [aptfeed].[TaskTracking]
WHERE TaskGuid IN (
SELECT TaskGuid
FROM [aptfeed].[TaskTracking]
WHERE TaskConfigId = 100
AND (TaskStatusId = 10 OR TaskStatusId = 20)
GROUP BY TaskGuid HAVING COUNT(*) = 2
)
AND TaskStatusId = 10 -- start
ORDER BY CreatedDate DESC
但这不起作用,因为它首先过滤了所有其他TaskStatusId。因此,几乎所有的COUNT(*)都将为2,即屏幕截图中的TaskConfigId = 40将被选中,因为第14行将被过滤。
此外,我觉得我正在使用的查询很慢,因为它必须将TaskConfigId的所有TaskGuid分组。有任何改善建议吗?
谢谢
答案 0 :(得分:1)
您可以通过一点点调整原始查询来找到TaskGuid:
SELECT TaskGuid
FROM [aptfeed].[TaskTracking]
WHERE TaskConfigId = 100
GROUP BY TaskGuid
HAVING COUNT(*) = 2
AND MIN(TaskStatusId) = 10
AND MAX(TaskStatusId) = 20
这将解决查找包含10和20(不一定按该顺序)且没有其他内容的组的问题。
但是您也可以使用窗口功能:
SELECT TaskConfigId, TaskGuid, MAX(CreatedDate)
FROM (
SELECT TaskConfigId
, TaskGuid
, ItemCount = COUNT(*) OVER (PARTITION BY TaskConfigId, TaskGuid)
, FirstStatus = FIRST_VALUE(TaskStatusId) OVER (PARTITION BY TaskConfigId, TaskGuid ORDER BY CreatedDate)
, LastStatus = LAST_VALUE(TaskStatusId) OVER (PARTITION BY TaskConfigId, TaskGuid ORDER BY CreatedDate)
, CreatedDate
FROM [aptfeed].[TaskTracking]
) AS cte
WHERE ItemCount = 2
AND FirstStatus = 10
AND LastStatus = 20
GROUP BY TaskConfigId, TaskGuid
答案 1 :(得分:1)
如果您要获取具有TaskStatusId 10和20(两个记录都应存在)的每个TaskConfigId,并找到最后一个CreatedDate,请尝试以下操作:
SELECT TaskGuid
FROM [TaskTracking]
WHERE TaskConfigId = 100
AND (TaskStatusId = 10 OR TaskStatusId = 20)
GROUP BY TaskGuid HAVING COUNT(*) = 2
如果需要,您还可以显示日期:
SELECT TaskGuid, MAX(CreatedDate) AS LastDate
FROM [TaskTracking]
WHERE TaskConfigId = 100
AND (TaskStatusId = 10 OR TaskStatusId = 20)
GROUP BY TaskGuid HAVING COUNT(*) = 2
答案 2 :(得分:0)
如果我做对了,那么您尝试获取的每个TaskConfigId
分别为TaskStatusId
10和20(两个记录都应该存在),并获取最后一个CreatedDate
他们每个人。
您可以执行以下操作:
SELECT *
FROM (
SELECT *
, COUNT(TaskGuid) OVER (PARTITION BY TaskGuid) TaskCount
, ROW_NUMBER() OVER (PARTITION BY TaskGuid ORDER BY CreatedDate DESC) RN
FROM
[aptfeed].[TaskTracking]
WHERE
TaskConfigId = 100
AND TaskStatusId IN(10,20)
) D
WHERE
TaskCount = 2
AND RN = 1