Подзапрос для получения определенных значений из таблицы

#sql #sql-server #subquery #sql-server-2016 #querying

#sql #sql-сервер #Подзапрос #sql-server-2016 #запрос

Вопрос:

Мне нужна помощь с запросами, и я сделаю все возможное, чтобы объяснить мою проблему. У меня есть следующая таблица ниже из 11 строк, которая создается путем импорта значений из списка SharePoint.

   ID   SHPT_ID  STATUS_DESC  REC_UPDT_DTTM  REC_CRTE_DTTM   EXPIR_DT
   1    270      Active      1-18-2019     1-19-2019     1-24-2019   
   2    270      In Progress 1-23-2019     1-24-2019     2-3-2019
   3    270      Completed   2-2-2019      2-3-2019      2-19-2019
   4    270      Completed   2-18-2019     2-19-2019    2-28-2019 
   5    270      In Progress 2-27-2019     2-28-2019    3-2-2019
   6    270      Completed   3-1-2019      3-2-2019     3-6-2019
   7    270      Completed   3-5-2019      3-6-2019     12-31-9999
   8    295      Active      12-20-2018    12-21-2018   12-26-2018
   9    295      Completed   12-25-2018    12-26-2018   12-31-9999
   10   345      Active      6-7-2017      6-8-2017     6-14-2017
   11   345      Completed   6-13-2017     6-14-2017    6-22-2017
   12   345      Completed   6-21-2017     6-22-2017    12-31-9999
 

Последняя запись, связанная с определенным идентификатором SharePoint, содержит EXPIR_DT (дата истечения срока действия) ’12/31/9999′. Каждый раз, когда значение в записи идентификатора SharePoint обновляется, создается новая строка.

Из этой таблицы я пытаюсь извлечь, в частности, 3 строки (строки, где ID = # 6, 9 и 11.)

Это записи, имеющие минимальное значение REC_UPDT_DTTM, когда STATUS_DESC равен «Завершено» в последний раз. Для строк, где SharePoint ID = 270, есть случай, когда запись была «Завершена», но была отменена на «В процессе», а затем позже была возвращена на «Завершено». Для этой записи она не должна занимать строку, где ID = 3, она должна занимать строкугде ID = 6.

Есть ли кто-нибудь, кто может помочь мне с этим кодом, поскольку я застрял в том, как продолжить, чтобы получить нужные строки? Я знаю, что мне нужно использовать подзапросы и функции, но на данный момент я действительно застрял.

Пожалуйста, дайте мне знать, если нужна дополнительная информация.

Ответ №1:

Этот запрос работает для приведенного выше набора данных. Однако, если SHPT_ID может содержать две завершенные записи в один и тот же день, это вернет две строки для этого SHPT_ID:

 SELECT m.*
FROM MyTable m
INNER JOIN (
    SELECT Min(Rec_UPDT_DTTM) MinUpdt,
        Shpt_ID
    FROM MyTable m1
    WHERE Status_Desc = 'Completed'
       AND NOT EXISTS (
           SELECT *
           FROM MyTable m2
           WHERE m2.Shpt_ID = m1.Shpt_ID
               AND m2.REC_UPDT_DTTM > m1.REC_UPDT_DTTM
               AND m2.Status_Desc <> 'Completed'
            )
    ) filter
    ON filter.MinUpdt = m.REC_UPDT_DTTM
    AND filter.Shpt_ID = m.Shpt_ID
 

Чтобы обработать случай с дубликатами в тот же день, код будет выглядеть следующим образом:

 SELECT MyTable.*
FROM MyTable
INNER JOIN (
    SELECT Shpt_ID, 
        MIN(ID) as ID
    FROM MyTable m
    INNER JOIN (
        SELECT Min(Rec_UPDT_DTTM) MinUpdt,
            Shpt_ID
        FROM MyTable
        WHERE Status_Desc = 'Completed'
       AND NOT EXISTS (
           SELECT *
           FROM MyTable m2
           WHERE m2.Shpt_ID = m1.Shpt_ID
               AND m2.REC_UPDT_DTTM > m1.REC_UPDT_DTTM
               AND m2.Status_Desc <> 'Completed'
            )
        ) filter
        ON filter.MinUpdt = MyTable.REC_UPDT_DTTM
        AND filter.Shpt_ID = MyTable.Shpt_ID
    ) as IDs
    ON MyTable.ID = IDs.ID
 

Ответ №2:

Не уверен, понял ли я вашу проблему, но поскольку формат даты — мм-дд-гггг, 2-2-2019 (# 3) меньше, чем 3-1-2019 (# 6).

Комментарии:

1. Да, вот почему я сказал для этого конкретного SharePoint ID..it первоначально был завершен, а затем выведен из этого статуса. Затем он был снова помещен в завершенный после «в процессе».

Ответ №3:

Используйте MIN и GROUP BY . Что-то вроде:

SELECT [ID], [SHPT_ID], [STATUS_DESC], MIN(REC_UPDT_DTTM), [REC_CRTE_DTTM], [EXPIR_DT] FROM [myTable] WHERE [STATUS_DESC] = 'Completed' GROUP BY [SHPT_ID] .

Комментарии:

1. Это не вернет полную строку, а только подмножество данных. OP запросил полную строку.

2. Вы можете использовать это как подзапрос, если списка идентификаторов первичного ключа недостаточно.