多列排序日期(有些包含空值)
Order dates with multiple columns (some containing nulls)
我有 4 个日期(来自单独的子查询),如下所示,但我想找到返回值的最大和最小日期。
我试过使用 CASE,它不适用于空值。
还尝试在 subs 中使用 COALESCE 来获取值,然后使用 CTE,但这也没有用。
(整体查询是在a1.id中查找没有-9的客户)
SO 中有很多帮助,但我无法满足此目的。
如有任何帮助,我们将不胜感激。
所需的列
PAT_ID Date1 Date2 Date3 Date4 MAX MIN
1 01/04/2015 25/12/2000 02/02/2011 01/04/2015 25/12/2000
2 05/08/1950 11/11/2011 11/11/2011 05/08/1950
3 1958 年 4 月 1 日 1958 年 4 月 1 日 1958 年 4 月 1 日
4 1900 年 1 月 1 日 1900 年 1 月 1 日
5 15/08/2017 07/07/1967 15/08/2017 07/07/1967
select distinct
ca1.id AS PT_ID,
(select Top 1 s1z.appointmen ApptDate
from schl_booking_appoin s1z
LEFT OUTER JOIN core_patient c3z ON s1z.patient = c3z.id
LEFT OUTER JOIN schl_appt_history_s s2z ON s1z.currentsta = s2z.id
LEFT OUTER JOIN applookup_instance a2z ON s2z.lkp_status = a2z.id
where (c3z.id = ca1.id and a2z.text not like '%cancelled%' and s1z.appointmen
> :SYS_DATE_TIME)
order by s1z.appointmen asc ) AS Date1,
(select Top 1
s1q.appointmen ApptDate
from schl_booking_appoin s1q
LEFT OUTER JOIN core_patient c3q ON s1q.patient = c3q.id
LEFT OUTER JOIN schl_appt_history_s s2q ON s1q.currentsta = s2q.id
LEFT OUTER JOIN applookup_instance a2q ON s2q.lkp_status = a2q.id
where (c3q.id = ca1.id and a2q.text not like '%cancelled%' and s1q.appointmen
< :SYS_DATE_TIME)
order by s1q.appointmen desc ) AS Date2,
(select top 1
CONVERT (VARCHAR(20),c2y.admissiond, 103) AdmissionDate
from core_admissiondetai c2y
LEFT OUTER JOIN core_pas_event c3y ON c2y.pasevent = c3y.id
LEFT OUTER JOIN core_patient c4y ON c3y.patient = c4y.id
where (c4y.id = ca1.id)
order by c2y.admissiond desc ) AS Date3,
(select top 1
CONVERT(VARCHAR(20),c5k.arrivaldat,103) ArrivalDate
from core_emergencyatten c5k
LEFT OUTER JOIN core_patient c6k ON c5k.patient = c6k.id
where (c6k.id = ca1.id)
order by c5k.arrivaldat desc ) AS Date4
from core_patient ca1
LEFT OUTER JOIN core_patient_c_identifi ca2 ON ca1.id = ca2.id
LEFT OUTER JOIN applookup_instance aa2 ON ca1.lkp_sex = aa2.id
LEFT OUTER JOIN applookup_instance aa1 ON ca2.lkp_c_ty = aa1.id
LEFT OUTER JOIN applookup_instance ab1 ON ca1.lkp_overseascl = ab1.id
LEFT OUTER JOIN core_organisation cx4 ON ca1.practice = cx4.id
WHERE ca1.id IN
(
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where ((ca2.merged = 0 or ca2.merged is null)
and aa1.id = -2404) )
AND ca1.id NOT IN (
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where (c1.namesurname not like '%XXTEST%'
and c1.namesurname not like '%ZZ%'
and a1.id = -9)
)
您可以执行以下操作:
- 将您的查询变成 CTE;
- 展平数据,使其成为 PT_IDs 和日期的列表;
- 从这个扁平化数据中找到每个 PT_ID 的最大和最小日期;
- 在最后一个查询中将所有这些重新组合在一起。
这是对上述所有操作的尝试:
WITH x AS (
select distinct
ca1.id AS PT_ID,
(select Top 1 s1z.appointmen ApptDate
from schl_booking_appoin s1z
LEFT OUTER JOIN core_patient c3z ON s1z.patient = c3z.id
LEFT OUTER JOIN schl_appt_history_s s2z ON s1z.currentsta = s2z.id
LEFT OUTER JOIN applookup_instance a2z ON s2z.lkp_status = a2z.id
where (c3z.id = ca1.id and a2z.text not like '%cancelled%' and s1z.appointmen
> :SYS_DATE_TIME)
order by s1z.appointmen asc ) AS Date1,
(select Top 1
s1q.appointmen ApptDate
from schl_booking_appoin s1q
LEFT OUTER JOIN core_patient c3q ON s1q.patient = c3q.id
LEFT OUTER JOIN schl_appt_history_s s2q ON s1q.currentsta = s2q.id
LEFT OUTER JOIN applookup_instance a2q ON s2q.lkp_status = a2q.id
where (c3q.id = ca1.id and a2q.text not like '%cancelled%' and s1q.appointmen
< :SYS_DATE_TIME)
order by s1q.appointmen desc ) AS Date2,
(select top 1
CONVERT (VARCHAR(20),c2y.admissiond, 103) AdmissionDate
from core_admissiondetai c2y
LEFT OUTER JOIN core_pas_event c3y ON c2y.pasevent = c3y.id
LEFT OUTER JOIN core_patient c4y ON c3y.patient = c4y.id
where (c4y.id = ca1.id)
order by c2y.admissiond desc ) AS Date3,
(select top 1
CONVERT(VARCHAR(20),c5k.arrivaldat,103) ArrivalDate
from core_emergencyatten c5k
LEFT OUTER JOIN core_patient c6k ON c5k.patient = c6k.id
where (c6k.id = ca1.id)
order by c5k.arrivaldat desc ) AS Date4
from core_patient ca1
LEFT OUTER JOIN core_patient_c_identifi ca2 ON ca1.id = ca2.id
LEFT OUTER JOIN applookup_instance aa2 ON ca1.lkp_sex = aa2.id
LEFT OUTER JOIN applookup_instance aa1 ON ca2.lkp_c_ty = aa1.id
LEFT OUTER JOIN applookup_instance ab1 ON ca1.lkp_overseascl = ab1.id
LEFT OUTER JOIN core_organisation cx4 ON ca1.practice = cx4.id
WHERE ca1.id IN
(
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where ((ca2.merged = 0 or ca2.merged is null)
and aa1.id = -2404) )
AND ca1.id NOT IN (
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where (c1.namesurname not like '%XXTEST%'
and c1.namesurname not like '%ZZ%'
and a1.id = -9)
)),
y AS (
SELECT PT_ID, Date1 AS [Date] FROM x WHERE Date1 IS NOT NULL
UNION ALL
SELECT PT_ID, Date2 AS [Date] FROM x WHERE Date2 IS NOT NULL
UNION ALL
SELECT PT_ID, Date3 AS [Date] FROM x WHERE Date3 IS NOT NULL
UNION ALL
SELECT PT_ID, Date4 AS [Date] FROM x WHERE Date4 IS NOT NULL),
z AS (
SELECT
PT_ID,
MIN([Date]) AS Min_Date,
MAX([Date]) AS Max_Date
FROM
y
GROUP BY
PT_ID)
SELECT
x.PT_ID,
x.Date1,
x.Date2,
x.Date3,
x.Date4,
z.Min_Date,
z.Max_Date
FROM
x
LEFT JOIN z ON z.PT_ID = x.PT_ID;
试试这个版本。您的旧查询充当子查询并引入新的列定义以获取最大日期。
SELECT PT_ID,
(
SELECT Max(v)
FROM (VALUES (Date1), (Date2), (Date3),(Date4)) AS value(v)
) as [MaxDate]
FROM
(
select distinct
ca1.id AS PT_ID,
(select Top 1 s1z.appointmen ApptDate
from schl_booking_appoin s1z
LEFT OUTER JOIN core_patient c3z ON s1z.patient = c3z.id
LEFT OUTER JOIN schl_appt_history_s s2z ON s1z.currentsta = s2z.id
LEFT OUTER JOIN applookup_instance a2z ON s2z.lkp_status = a2z.id
where (c3z.id = ca1.id and a2z.text not like '%cancelled%' and s1z.appointmen
> :SYS_DATE_TIME)
order by s1z.appointmen asc ) AS Date1,
(select Top 1
s1q.appointmen ApptDate
from schl_booking_appoin s1q
LEFT OUTER JOIN core_patient c3q ON s1q.patient = c3q.id
LEFT OUTER JOIN schl_appt_history_s s2q ON s1q.currentsta = s2q.id
LEFT OUTER JOIN applookup_instance a2q ON s2q.lkp_status = a2q.id
where (c3q.id = ca1.id and a2q.text not like '%cancelled%' and s1q.appointmen
< :SYS_DATE_TIME)
order by s1q.appointmen desc ) AS Date2,
(select top 1
CONVERT (VARCHAR(20),c2y.admissiond, 103) AdmissionDate
from core_admissiondetai c2y
LEFT OUTER JOIN core_pas_event c3y ON c2y.pasevent = c3y.id
LEFT OUTER JOIN core_patient c4y ON c3y.patient = c4y.id
where (c4y.id = ca1.id)
order by c2y.admissiond desc ) AS Date3,
(select top 1
CONVERT(VARCHAR(20),c5k.arrivaldat,103) ArrivalDate
from core_emergencyatten c5k
LEFT OUTER JOIN core_patient c6k ON c5k.patient = c6k.id
where (c6k.id = ca1.id)
order by c5k.arrivaldat desc ) AS Date4
from core_patient ca1
LEFT OUTER JOIN core_patient_c_identifi ca2 ON ca1.id = ca2.id
LEFT OUTER JOIN applookup_instance aa2 ON ca1.lkp_sex = aa2.id
LEFT OUTER JOIN applookup_instance aa1 ON ca2.lkp_c_ty = aa1.id
LEFT OUTER JOIN applookup_instance ab1 ON ca1.lkp_overseascl = ab1.id
LEFT OUTER JOIN core_organisation cx4 ON ca1.practice = cx4.id
WHERE ca1.id IN
(
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where ((ca2.merged = 0 or ca2.merged is null)
and aa1.id = -2404) )
AND ca1.id NOT IN (
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where (c1.namesurname not like '%XXTEST%'
and c1.namesurname not like '%ZZ%'
and a1.id = -9)
)
)Sub
我有 4 个日期(来自单独的子查询),如下所示,但我想找到返回值的最大和最小日期。 我试过使用 CASE,它不适用于空值。 还尝试在 subs 中使用 COALESCE 来获取值,然后使用 CTE,但这也没有用。
(整体查询是在a1.id中查找没有-9的客户)
SO 中有很多帮助,但我无法满足此目的。
如有任何帮助,我们将不胜感激。 所需的列 PAT_ID Date1 Date2 Date3 Date4 MAX MIN 1 01/04/2015 25/12/2000 02/02/2011 01/04/2015 25/12/2000 2 05/08/1950 11/11/2011 11/11/2011 05/08/1950 3 1958 年 4 月 1 日 1958 年 4 月 1 日 1958 年 4 月 1 日 4 1900 年 1 月 1 日 1900 年 1 月 1 日 5 15/08/2017 07/07/1967 15/08/2017 07/07/1967
select distinct
ca1.id AS PT_ID,
(select Top 1 s1z.appointmen ApptDate
from schl_booking_appoin s1z
LEFT OUTER JOIN core_patient c3z ON s1z.patient = c3z.id
LEFT OUTER JOIN schl_appt_history_s s2z ON s1z.currentsta = s2z.id
LEFT OUTER JOIN applookup_instance a2z ON s2z.lkp_status = a2z.id
where (c3z.id = ca1.id and a2z.text not like '%cancelled%' and s1z.appointmen
> :SYS_DATE_TIME)
order by s1z.appointmen asc ) AS Date1,
(select Top 1
s1q.appointmen ApptDate
from schl_booking_appoin s1q
LEFT OUTER JOIN core_patient c3q ON s1q.patient = c3q.id
LEFT OUTER JOIN schl_appt_history_s s2q ON s1q.currentsta = s2q.id
LEFT OUTER JOIN applookup_instance a2q ON s2q.lkp_status = a2q.id
where (c3q.id = ca1.id and a2q.text not like '%cancelled%' and s1q.appointmen
< :SYS_DATE_TIME)
order by s1q.appointmen desc ) AS Date2,
(select top 1
CONVERT (VARCHAR(20),c2y.admissiond, 103) AdmissionDate
from core_admissiondetai c2y
LEFT OUTER JOIN core_pas_event c3y ON c2y.pasevent = c3y.id
LEFT OUTER JOIN core_patient c4y ON c3y.patient = c4y.id
where (c4y.id = ca1.id)
order by c2y.admissiond desc ) AS Date3,
(select top 1
CONVERT(VARCHAR(20),c5k.arrivaldat,103) ArrivalDate
from core_emergencyatten c5k
LEFT OUTER JOIN core_patient c6k ON c5k.patient = c6k.id
where (c6k.id = ca1.id)
order by c5k.arrivaldat desc ) AS Date4
from core_patient ca1
LEFT OUTER JOIN core_patient_c_identifi ca2 ON ca1.id = ca2.id
LEFT OUTER JOIN applookup_instance aa2 ON ca1.lkp_sex = aa2.id
LEFT OUTER JOIN applookup_instance aa1 ON ca2.lkp_c_ty = aa1.id
LEFT OUTER JOIN applookup_instance ab1 ON ca1.lkp_overseascl = ab1.id
LEFT OUTER JOIN core_organisation cx4 ON ca1.practice = cx4.id
WHERE ca1.id IN
(
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where ((ca2.merged = 0 or ca2.merged is null)
and aa1.id = -2404) )
AND ca1.id NOT IN (
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where (c1.namesurname not like '%XXTEST%'
and c1.namesurname not like '%ZZ%'
and a1.id = -9)
)
您可以执行以下操作:
- 将您的查询变成 CTE;
- 展平数据,使其成为 PT_IDs 和日期的列表;
- 从这个扁平化数据中找到每个 PT_ID 的最大和最小日期;
- 在最后一个查询中将所有这些重新组合在一起。
这是对上述所有操作的尝试:
WITH x AS (
select distinct
ca1.id AS PT_ID,
(select Top 1 s1z.appointmen ApptDate
from schl_booking_appoin s1z
LEFT OUTER JOIN core_patient c3z ON s1z.patient = c3z.id
LEFT OUTER JOIN schl_appt_history_s s2z ON s1z.currentsta = s2z.id
LEFT OUTER JOIN applookup_instance a2z ON s2z.lkp_status = a2z.id
where (c3z.id = ca1.id and a2z.text not like '%cancelled%' and s1z.appointmen
> :SYS_DATE_TIME)
order by s1z.appointmen asc ) AS Date1,
(select Top 1
s1q.appointmen ApptDate
from schl_booking_appoin s1q
LEFT OUTER JOIN core_patient c3q ON s1q.patient = c3q.id
LEFT OUTER JOIN schl_appt_history_s s2q ON s1q.currentsta = s2q.id
LEFT OUTER JOIN applookup_instance a2q ON s2q.lkp_status = a2q.id
where (c3q.id = ca1.id and a2q.text not like '%cancelled%' and s1q.appointmen
< :SYS_DATE_TIME)
order by s1q.appointmen desc ) AS Date2,
(select top 1
CONVERT (VARCHAR(20),c2y.admissiond, 103) AdmissionDate
from core_admissiondetai c2y
LEFT OUTER JOIN core_pas_event c3y ON c2y.pasevent = c3y.id
LEFT OUTER JOIN core_patient c4y ON c3y.patient = c4y.id
where (c4y.id = ca1.id)
order by c2y.admissiond desc ) AS Date3,
(select top 1
CONVERT(VARCHAR(20),c5k.arrivaldat,103) ArrivalDate
from core_emergencyatten c5k
LEFT OUTER JOIN core_patient c6k ON c5k.patient = c6k.id
where (c6k.id = ca1.id)
order by c5k.arrivaldat desc ) AS Date4
from core_patient ca1
LEFT OUTER JOIN core_patient_c_identifi ca2 ON ca1.id = ca2.id
LEFT OUTER JOIN applookup_instance aa2 ON ca1.lkp_sex = aa2.id
LEFT OUTER JOIN applookup_instance aa1 ON ca2.lkp_c_ty = aa1.id
LEFT OUTER JOIN applookup_instance ab1 ON ca1.lkp_overseascl = ab1.id
LEFT OUTER JOIN core_organisation cx4 ON ca1.practice = cx4.id
WHERE ca1.id IN
(
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where ((ca2.merged = 0 or ca2.merged is null)
and aa1.id = -2404) )
AND ca1.id NOT IN (
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where (c1.namesurname not like '%XXTEST%'
and c1.namesurname not like '%ZZ%'
and a1.id = -9)
)),
y AS (
SELECT PT_ID, Date1 AS [Date] FROM x WHERE Date1 IS NOT NULL
UNION ALL
SELECT PT_ID, Date2 AS [Date] FROM x WHERE Date2 IS NOT NULL
UNION ALL
SELECT PT_ID, Date3 AS [Date] FROM x WHERE Date3 IS NOT NULL
UNION ALL
SELECT PT_ID, Date4 AS [Date] FROM x WHERE Date4 IS NOT NULL),
z AS (
SELECT
PT_ID,
MIN([Date]) AS Min_Date,
MAX([Date]) AS Max_Date
FROM
y
GROUP BY
PT_ID)
SELECT
x.PT_ID,
x.Date1,
x.Date2,
x.Date3,
x.Date4,
z.Min_Date,
z.Max_Date
FROM
x
LEFT JOIN z ON z.PT_ID = x.PT_ID;
试试这个版本。您的旧查询充当子查询并引入新的列定义以获取最大日期。
SELECT PT_ID,
(
SELECT Max(v)
FROM (VALUES (Date1), (Date2), (Date3),(Date4)) AS value(v)
) as [MaxDate]
FROM
(
select distinct
ca1.id AS PT_ID,
(select Top 1 s1z.appointmen ApptDate
from schl_booking_appoin s1z
LEFT OUTER JOIN core_patient c3z ON s1z.patient = c3z.id
LEFT OUTER JOIN schl_appt_history_s s2z ON s1z.currentsta = s2z.id
LEFT OUTER JOIN applookup_instance a2z ON s2z.lkp_status = a2z.id
where (c3z.id = ca1.id and a2z.text not like '%cancelled%' and s1z.appointmen
> :SYS_DATE_TIME)
order by s1z.appointmen asc ) AS Date1,
(select Top 1
s1q.appointmen ApptDate
from schl_booking_appoin s1q
LEFT OUTER JOIN core_patient c3q ON s1q.patient = c3q.id
LEFT OUTER JOIN schl_appt_history_s s2q ON s1q.currentsta = s2q.id
LEFT OUTER JOIN applookup_instance a2q ON s2q.lkp_status = a2q.id
where (c3q.id = ca1.id and a2q.text not like '%cancelled%' and s1q.appointmen
< :SYS_DATE_TIME)
order by s1q.appointmen desc ) AS Date2,
(select top 1
CONVERT (VARCHAR(20),c2y.admissiond, 103) AdmissionDate
from core_admissiondetai c2y
LEFT OUTER JOIN core_pas_event c3y ON c2y.pasevent = c3y.id
LEFT OUTER JOIN core_patient c4y ON c3y.patient = c4y.id
where (c4y.id = ca1.id)
order by c2y.admissiond desc ) AS Date3,
(select top 1
CONVERT(VARCHAR(20),c5k.arrivaldat,103) ArrivalDate
from core_emergencyatten c5k
LEFT OUTER JOIN core_patient c6k ON c5k.patient = c6k.id
where (c6k.id = ca1.id)
order by c5k.arrivaldat desc ) AS Date4
from core_patient ca1
LEFT OUTER JOIN core_patient_c_identifi ca2 ON ca1.id = ca2.id
LEFT OUTER JOIN applookup_instance aa2 ON ca1.lkp_sex = aa2.id
LEFT OUTER JOIN applookup_instance aa1 ON ca2.lkp_c_ty = aa1.id
LEFT OUTER JOIN applookup_instance ab1 ON ca1.lkp_overseascl = ab1.id
LEFT OUTER JOIN core_organisation cx4 ON ca1.practice = cx4.id
WHERE ca1.id IN
(
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where ((ca2.merged = 0 or ca2.merged is null)
and aa1.id = -2404) )
AND ca1.id NOT IN (
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where (c1.namesurname not like '%XXTEST%'
and c1.namesurname not like '%ZZ%'
and a1.id = -9)
)
)Sub