I have a SELECT query with different sub-queries inside a CASE statement. I need to re-use them to get other columns inside same general SELECT.
Two main tables are:
Event
+------------+----------------------------+-------------+-----------------------------+
| Id | EventTypeId | PersonId | Name |DateEvent
+------------+----------------------------+-------------+-----------------------------+
| 2307 | 4 | 2189 | Migrated | 1900-01-01 00:00:00.6780000 |
| 2308 | 15 | 2189 | Birthday | 2020-09-18 16:48:32.6870000 |
| 2309 | 15 | 2190 | Birthday | 2012-01-01 00:00:00.0000000 |
| 3401 | 6 | 2190 | Moved | 2013-03-12 00:00:00.0000000 |
| 3402 | 15 | 3001 | Birthday | 2020-08-21 16:48:32.6870000 |
| 3410 | 6 | 3001 | Moved | 1900-01-01 00:00:00.0000000 |
| 3440 | 6 | 2190 | Moved | 2016-03-12 00:00:00.0000000 |
| 4000 | 3 | 3001 | Transfer | 2021-01-10 00:00:00.0000000 |
| 4020 | 3 | 4020 | Transfer | 2016-03-12 00:00:00.0000000 |
Person
+------------+----------------+-------------------+-----------+-------------------------------+
| Id | UCNumber | Name |LastName | Birth |
+------------+----------------+-------------------+-----------+-------------------------------+
| 2189 | 004947 | John | Smith | 1900-01-01 00:00:00.0000000 |
| 2190 | 006857 | Alice | Timo | 1982-02-20 00:00:00.0000000 |
| 3001 | 006594 | Tom | Zigo | 1981-03-21 00:00:00.0000000 |
| 4020 | 007263 | Alice | Bilani | 1973-04-03 00:00:00.0000000 |
Multiple events can be associated to a Person.
The query is:
Select
[UC_Number] = A.UCNumber,
[Name] = ltrim(rtrim(A.FirstName + ' ' + A.LastName)),
[Stat_Code] = case
when A.Id in (select P.Id from db.dbo.Person as P
cross apply
(select top 1 id, Name, DateEvent, EventTypeId
from db.dbo.Event
where PersonId = P.Id and EventTypeId not in (8, 14, 17)
order by DateEvent desc) le
where le.EventTypeId = 5) then 'AR'
when A.Id in (select P.Id from db.dbo.Person as P
cross apply
(select top 1 id, Name, DateEvent, EventTypeId
from db.dbo.Event
where PersonId = P.Id and EventTypeId not in (8, 14, 17)
order by DateEvent desc) le
where le.EventTypeId = 4) then 'AW'
when A.DateB is not null then 'ABC'
when A.Id in (select P.Id from db.dbo.Person as P
cross apply
(select top 1 id, Name, DateEvent, EventTypeId
from db.dbo.Event
where PersonId = P.Id and EventTypeId not in (8, 14, 17)
order by DateEvent desc) as le
where le.EventTypeId = 15) then 'AT'
when A.Id in (select P.Id from db.dbo.Person as P
cross apply
(select top 1 id, Name, DateEvent, EventTypeId
from db.dbo.Event
where PersonId = P.Id and EventTypeId not in (8, 14, 17)
order by DateEvent desc) le
where le.EventTypeId = 6) then 'ASPEC'
when A.Id in (select P.Id from db.dbo.Person as P
cross apply
(select top 1 id, Name, DateEvent, EventTypeId
from db.dbo.Event
where PersonId = P.Id and EventTypeId not in (8, 14, 17)
order by DateEvent desc) le
left join db.dbo.Address B on P.AddressResidenceId = B.Id
where le.EventTypeId = 3 and B.PostCode is null) then 'AK'
else 'OK'
end,
[Status] = case
when A.Id in (select P.Id from db.dbo.Person as P
cross apply
(select top 1 id, Name, DateEvent, EventTypeId
from db.dbo.Event
where PersonId = P.Id and EventTypeId not in (8, 14, 17)
order by DateEvent desc) le
where le.EventTypeId = 4) then 'OtherD'
when A.Id in (select P.Id from db.dbo.Person as P
cross apply
(select top 1 id, Name, DateEvent, EventTypeId
from db.dbo.Event
where PersonId = P.Id and EventTypeId not in (8, 14, 17)
order by DateEvent desc) as le
where le.EventTypeId = 6) then 'OtherE'
when A.Id in (select P.Id from db.dbo.Person as P
cross apply
(select top 1 id, Name, DateEvent, EventTypeId
from db.dbo.Event
where PersonId = P.Id and EventTypeId not in (8, 14, 17)
order by DateEvent desc) le
left join db.dbo.Address B on P.AddressResidenceId = B.Id
where le.EventTypeId = 3 and B.PostCode is null) then 'OtherW'
when A.Id in (select P.Id from db.dbo.Person as P
cross apply
(select top 1 id, Name, DateEvent, EventTypeId
from db.dbo.Event
where PersonId = P.Id and EventTypeId not in (8, 14, 17)
order by DateEvent desc) as le
where le.EventTypeId = 15) then 'OtherB'
else 'NO'
End
From db.dbo.Person A ...
left join Address B on A.AddressResidenceId = B.Id
...
Expected result:
+-----------+--------------+-----------+--------+
| UC_Number | Name | Stat_Code | Status |
+-----------+--------------+-----------+--------+
| 004947 | John Smith | AT | OtherB |
+-----------+--------------+-----------+--------+
| 006857 | Alice Timo | ASPEC | OtherE |
+-----------+--------------+-----------+--------+
| 006594 | Tom Zigo | AK | OtherW |
+-----------+--------------+-----------+--------+
| 007263 | Alice Bilani | AK | OtherW |
+-----------+--------------+-----------+--------+
If you check the Status
column I re-used same sub-queries. Is there another way to make the script parts not to be repeated ?