#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. Вы можете использовать это как подзапрос, если списка идентификаторов первичного ключа недостаточно.