SQL: Как проверить значения в группе? - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть такая таблица:

enter image description here

Для каждого TaskConfigId есть TaskGuid.Если TaskGuid одинаков для того же TaskConfigId, кажется, что они для одной и той же задачи.Обычно TaskStatusId будет 10 или 20. Когда что-то случится, TaskStatusId будет иметь другие значения, например 15. Но для каждой задачи у него всегда есть 10 и 20.

Итак, если статус задачи имеет10 и 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.

Кроме того, я чувствую, что используемый мной запрос медленныйтак как он должен сгруппировать все TaskGuid для TaskConfigId.Любые предложения по улучшению этого?

Спасибо

Ответы [ 3 ]

0 голосов
/ 01 февраля 2019

Если я правильно понял, вы пытаетесь получить все 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
0 голосов
/ 01 февраля 2019

Если вы пытаетесь получить каждый TaskConfigId с TaskStatusId 10 и 20 (обе записи должны существовать) и найти последнюю 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  
0 голосов
/ 01 февраля 2019

Вы можете найти 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
...