Должен ли я использовать OUTER APPLY для привязки номера Id к имени человека? - PullRequest
1 голос
/ 14 января 2020

Я работаю с 2 таблицами. Это древние таблицы, которые я НЕ могу редактировать самостоятельно. Я должен работать со структурой, данной мне в этом случае.

У каждого есть «CaseID» и код события, например:

Таблица 1:

| CaseID | Event |   Date   |
|:------:|:-----:|:--------:|
|  BL221 |  FTA  | 02/01/19 |
|  BL331 |  FTA  | 03/01/19 |
|  BL444 |  FTA  | 05/01/19 |
|  BL444 |  FTA  | 05/01/19 |
|  BL881 |  FTA  | 12/01/19 |
|  BL991 |  BEW  | 05/01/19 |
|  BL995 |  BEW  | 12/01/19 |

У одного CaseID может быть много разных событий, включая дубликаты ( 2 события "FTA" на BL444). В данном случае меня интересуют '1008 *

' FTA '. Моя другая таблица связывает эти CaseID с отдельным лицом, с его именем и идентификатором пользователя, например:

Таблица 2:

| FirstName | LastName | UsrID | CaseID |
|:---------:|:--------:|:-----:|:------:|
|  Jessica  |   Smith  |  885  |  BL111 |
|  Jessica  |   Smith  |  885  |  BL221 |
|  Jessica  |   Smith  |  885  |  BL331 |
|  Jessica  |   Smith  |  885  |  BL444 |
|  Jessica  |  Stanley |  885  |  BL881 |

Как видите, Джессика недавно вышла замуж. Ее UsrID останется прежним (885), но мне нужно иметь возможность связать ее новое имя с этим идентификатором в запросе.

Мы используем CaseID, чтобы определить, в каком направлении мы движемся во времени, поскольку они последовательный.

Как уже упоминалось, я просто пытаюсь подсчитать отдельные экземпляры события FTA, выяснить, сколько на CaseID, и приклеить их (наиболее актуальное) имя в конце. С примерами данных, которые я хотел бы увидеть:

|       Name       | UsrID | Hits | NumofCases |
|:----------------:|:-----:|:----:|:----------:|
| Stanley, Jessica |  885  |   5  |      4     |
|     Doe, John    |  225  |   2  |      1     |

То, что я пробовал до сих пор:

SELECT TB.NAME_LAST + ', ' + TB.NAME_FIRST as Name,  TB.UsrID, COUNT(TB.UsrID) as Hits, COUNT(DISTINCT(TA.CaseID)) as NumofCases
FROM Table1 as TA
JOIN Table2 as TB on TA.CaseID = TB.CaseID
where TA.DT_COURT_EVENT between '20190201' and '20200101' and TA.Event = 'FTA'
group by TB.NAME_LAST + ', ' + TB.NAME_FIRST, TB.UsrID
order by Hits desc

Это довольно близко, но эта неприятная GROUP BY заставляет меня разделите все экземпляры, как только имя Джессики будет изменено:

|       Name       | UsrID | Hits | NumofCases |
|:----------------:|:-----:|:----:|:----------:|
|  Smith, Jessica  |  885  |   4  |      3     |
|     Doe, John    |  225  |   2  |      1     |
| Stanley, Jessica |  885  |   1  |      1     |

Итак, я попробовал это:

SELECT TB.UsrID, COUNT(TB.UsrID) as Hits, COUNT(DISTINCT(TA.CaseID)) as NumofCases, C.Name
from Table1 TA
JOIN Table2 as TB on TA.CaseID = TB.CaseID
OUTER APPLY (SELECT TOP 1 (C.NAME_LAST + ',' + C.NAME_First) as Name
                    FROM   Table2 C
                    WHERE  TA.CaseID = C.CaseID
                    ORDER  BY TA.Date desc) C
where TA.Date between '20190901' and '20200101' and TA.Event = 'FTA'
group by TB.UsrID, C.Name
order by Hits desc

Поскольку я полагал, что «Выбрать ТОП 1» будет то, что я хотел, но я получить те же результаты, что и раньше.

Я хочу избежать проблемы XY здесь, поэтому я прошу прощения за многословность и прикольный заголовок. Просто хочу показать все мои карты на случай, если я буду неэффективно это делать

Спасибо.

Ответы [ 2 ]

1 голос
/ 14 января 2020

Вы можете использовать CROSS APPLY или OUTER APPLY, как вы изначально предполагали, но вам нужно присоединиться к UsrID и исправить порядок сортировки.

SELECT ca.Name, t2.UsrID, COUNT(*) AS Hits, COUNT(DISTINCT t1.CaseID) AS NumofCases
FROM Table1 t1
INNER JOIN Table2 t2 ON t2.CaseID = t1.CaseID
CROSS APPLY (SELECT TOP 1 LastName + ', ' + FirstName as Name
             FROM Table2
             WHERE UsrID = t2.UsrID
             ORDER BY CaseID DESC) ca
WHERE t1.Event = 'FTA'
GROUP BY ca.Name, t2.UsrID
0 голосов
/ 14 января 2020

Понятно. Это странная установка. Вы можете использовать условное агрегирование:

select userid, count(*), count(distinct caseid),
       max(case when seqnum = 1 then name end)
from (select t1.*, t2.last_name + ' ' + t2.first_name as name
             row_number() over (partition by t2.usrid order by t1.date desc) as seqnum
      from table1 t1 join 
           table2 t2
           on t1.caseid = t2.caseid
      where t1.event = 'FA'
     ) t12
group by userid;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...