Должен ли я использовать OUTER APPLY для привязки номера Id к имени человека?

Я работаю с 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). В этом случае я заинтересован в 'FTA'

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

Таблица 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 �' and �' 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 �' and �' and TA.Event = 'FTA'
group by TB.UsrID, C.Name
order by Hits desc

Потому что я подумал, что «Select TOP 1» будет тем, что я хотел, но я получаю те же результаты, что и раньше.

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

Спасибо.

Всего 2 ответа


Вы можете использовать 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

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

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;

Есть идеи?

10000