#sql #tsql
#sql #tsql
Вопрос:
СЦЕНАРИЙ:
Представьте таблицу, подобную этой:
Auto_INC, UserID_FK, CaseID_FK, Date
idX userX caseX
и когда она заполнена, это выглядит так:
id1, user4, case20, 2010/01/12
id2, user1, case13, 2010/03/20
id3, user2, case10, 2010/03/22
id4, user1, case21, 2011/01/10
id5, user2, case9, 2011/01/11
id6, user3, case20, 2011/02/01
id7, user1, case9, 2011/03/25
ВОПРОС:
Как мне получить ОДНУ запись ОБРАЩЕНИЯ с назначенным ПОСЛЕДНИМ пользователем??
Таким образом, если был назначен один пользователь, он автоматически переопределит всех предыдущих пользователей в этом случае.
Что-то вроде этого:
id7, user1, case9, 2011/03/25
id2, user1, case13, 2010/03/20
id4, user1, case21, 2011/01/10
id6, user3, case20, 2011/02/01
id3, user2, case10, 2010/03/22
В этом случае пользователю 1 было назначено 3 случая, пользователю 2 — 2 случая, но один был переопределен пользователем 1, у пользователя 3 был 1 случай, и он переопределил User4 … так что Пользователь4 не получает никакого случая .. поэтому он не появится в списке.
ОБРАТИТЕ ВНИМАНИЕ НА ПРЕИМУЩЕСТВА
В идеале мы должны получать в результате .. столько записей, сколько СЛУЧАЕВ в исходной таблице!!!
Ответ №1:
declare @T table
(
Auto_INC int identity primary key,
UserID_FK int,
CaseID_FK int,
[Date] date
);
insert into @T values
(4, 20, '2010/01/12'),
(1, 13, '2010/03/20'),
(2, 10, '2010/03/22'),
(1, 21, '2010/01/10'),
(2, 9, '2010/01/11'),
(3, 20, '2010/02/01'),
(1, 9, '2010/03/25');
with C as
(
select *,
row_number() over(partition by CaseID_FK
order by [Date] desc) as rn
from @T
)
select Auto_INC, UserID_FK, CaseID_FK, [Date]
from C
where rn = 1;
Результат:
Auto_INC UserID_FK CaseID_FK Date
----------- ----------- ----------- ----------
7 1 9 2010-03-25
3 2 10 2010-03-22
2 1 13 2010-03-20
6 3 20 2010-02-01
4 1 21 2010-01-10
Комментарии:
1. Мне пришлось отредактировать свой первоначальный пост, потому что было неясно, что мне нужно получить столько записей, сколько есть СЛУЧАЕВ… с помощью этого SQL я получаю столько записей, сколько … Пользователи.
2. Это правильный синтаксис и результат. Вопрос был изменен, поэтому этот результат больше не является правильным
3. Я согласен… этот ответ возвращал правильный результат, но проблема была на моей стороне, где я неправильно сформулировал вопрос.
4. @Filu, обновленный ответ. С вашим измененным требованием все уже не так сложно.
5. Достаточно забавно… правильный ответ — это как предыдущий, так и этот текущий. Потрясающая мощь SQL, но еще более поразительны знания, которые вы имеете с TSQL 🙂
Ответ №2:
Вы можете выполнить подзапрос в той же таблице, чтобы получить последнего пользователя (и дату для этого пользователя).
SELECT DISTINCT T1.CaseID_FK, (SELECT TOP 1 T2.UserID_FK
FROM Table AS T2
WHERE T2.CaseID_FK = T1.CaseID_FK
ORDER BY T2.Date DESC) AS User,
(SELECT TOP 1 T2.Date
FROM Table AS T2
WHERE T2.CaseID_FK = T1.CaseID_FK
ORDER BY T2.Date DESC) AS Date,
FROM Table AS T1
Редактировать:
Это должно ограничиваться возвратом только количества строк по мере того, как у вас есть случаи.
SELECT *
FROM
(SELECT T1.CaseID_FK, MAX(T1.Date) AS Date
FROM Table AS T1
GROUP BY CaseID_FK) AS T2 LEFT JOIN
(SELECT *
FROM Table AS T3) AS T4 ON T2.CaseID_FK = T4.CaseID_FK AND T2.Date = T4.Date
Комментарии:
1. Я обновил начальный пост, потому что он не был очищен. С помощью этого запроса, если в исходной таблице 1000 записей, я получаю результирующий набор из 1000 записей.
Ответ №3:
использовать
SELECT * FROM TABLE T WHERE
(T.CASEID_FK, T.Auto_INC) IN
(
SELECT A.CASEID_FK, MAX (A.Auto_INC) MI FROM TABLE A
INNER JOIN (SELECT X.CASEID_FK, MAX (X.DATE) MD FROM TABLE X GROUP BY X.CASEID_FK) Y ON A.DATE = Y.MD AND A.CASEID_FK = Y.CASEID_FK
GROUP BY A.CASEID_FK
)