#sql-server #tsql #max #multiple-columns
#sql-сервер #tsql #макс #несколько столбцов
Вопрос:
У меня есть таблица с
EMPLOYEE_CODE,
ENTITLEMENT_CODE,
TRANS_DATE,
UNIQUE_ID,
HOURS.
Мне нужно получить ЧАСЫ для максимума TRANS_DATE
для каждой комбинации EMPLOYEE_CODE
, ENTITLEMENT_CODE
но возможно, что будет несколько случаев максимального TRANS_DATE, поэтому мне нужно дополнительно уточнить запрос, чтобы получить максимум UNIQUE_ID
и, следовательно, ЧАСЫ для этой конкретной строки, которая вернулась. Я пробовал разные методы, но я могу получить часть запроса, но не все вместе.
Так что у меня может быть что-то вроде:
EMPLOYEE_CODE, ENTITLEMENT_CODE, TRANS_DATE, UNIQUE_ID, HOURS.
-----------------------------------------------------------------
2305 ANNL 04/15/2014 28547 15.55
2305 ANNL 04/15/2014 28622 16.83
2305 ANNL 04/15/2014 28223 18.62
2305 ANNL 04/08/2014 28111 12.22
2305 SICK 04/12/2014 28150 14.47
2305 SICK 04/12/2014 28162 12.44
2305 SICK 03/11/2014 28062 18.66
Так что это должно было бы вернуть
16.83 for 2305 ANNL
12.44 for 2305 SICK
Любая помощь очень ценится.
Ответ №1:
Попробуйте это:
;WITH CTE
AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY EMPLOYEE_CODE, ENTITLEMENT_CODE
ORDER BY TRANS_DATE DESC, UNIQUE_ID DESC) rn
FROM tbl
)
SELECT
EMPLOYEE_CODE,
ENTITLEMENT_CODE,
HOURS
FROM CTE
WHERE rn = 1
Комментарии:
1. Это хорошо сработало, Гамлет. Я раньше не использовал CTE, поэтому я изучу его немного подробнее, чтобы улучшить свое понимание, но запрос вернул то, что я ожидал. Ваша помощь приветствуется.
Ответ №2:
Попробуйте использовать row_number()
с partition by clause
select * from
(
select *,rn=row_number()over(partition by ENTITLEMENT_CODE order by UNIQUE_ID desc)
from table
)x
where x.rn=1
Ответ №3:
Если вы предпочитаете использовать коррелированный подзапрос:
SELECT HOURS, EMPLOYEE_CODE, ENTITLEMENT_CODE
FROM mytable T1
WHERE NOT EXISTS
(
SELECT *
FROM mytable T2
WHERE T2.EMPLOYEE_CODE = T1.EMPLOYEE_CODE
AND T2.ENTITLEMENT_CODE = T1.ENTITLEMENT_CODE
AND (T2.TRANS_DATE > T1.TRANS_DATE
OR T2.TRANS_DATE = T1.TRANS_DATE AND T2.UNIQUE_ID > T1.UNIQUE_ID)
)
Желательно, чтобы у вас был индекс поверх EMPLOYEE_CODE
и ENTITLEMENT_CODE
(составной), чтобы это работало эффективно.
Ответ №4:
Может быть что-то вроде этого
Select T.* From Table1 T JOIN
( Select Max(S.UNIQUE_ID) MaxUniq,S.EMPLOYEE_CODE,S.ENTITLEMENT_CODE
From Table1 S Join
( Select T1.EMPLOYEE_CODE,T1.ENTITLEMENT_CODE,Max(T1.TRANS_DATE) As MaxDate
From Table1 T1 Group By T1.EMPLOYEE_CODE,T1.ENTITLEMENT_CODE
) JR On S.TRANS_DATE = JR.MaxDate AND S.EMPLOYEE_CODE = JR.EMPLOYEE_CODE AND S.ENTITLEMENT_CODE = JR.ENTITLEMENT_CODE
Group By S.EMPLOYEE_CODE,S.ENTITLEMENT_CODE
)R ON T.UNIQUE_ID = R.MaxUniq
Вывод будет:
EMPLOYEE_CODE ENTITLEMENT_CODE TRANS_DATE UNIQUE_ID HOURS
2305 ANNL 2014-04-15 28622 16.83
2305 SICK 2014-04-12 28162 12.44
Комментарии:
1. Это хорошо сработало, Виньеш, и вернуло то, что я ожидал. Я не уверен, имеет ли это преимущества по сравнению с опубликованным решением CTE. Ваша помощь приветствуется.