令我困扰的是,对于一个简单的查询,我必须写出这么多的子选择和WITH语句。
问题是:是否有关于如何简化具有子查询的查询的基本指南?
这是我的疑问:
WITH cte_min
AS (SELECT a.client_id,
a.specimen_source,
a.received_date
FROM f_accession_daily a
JOIN (SELECT DISTINCT f.client_id,
f.received_date,
f.accession_daily_key
FROM F_ACCESSION_DAILY f
JOIN (SELECT CLIENT_ID,
Min(received_date) MinRecDate
FROM F_ACCESSION_DAILY
GROUP BY CLIENT_ID) i
ON f.CLIENT_ID = i.CLIENT_ID
AND f.RECEIVED_DATE = i.MinRecDate) b
ON a.ACCESSION_DAILY_KEY = b.ACCESSION_DAILY_KEY),
cte_max
AS (SELECT a.client_id,
a.specimen_source,
a.received_date
FROM f_accession_daily a
JOIN (SELECT DISTINCT f.client_id,
f.received_date,
f.accession_daily_key
FROM F_ACCESSION_DAILY f
JOIN (SELECT CLIENT_ID,
Max(received_date) MaxRecDate
FROM F_ACCESSION_DAILY
GROUP BY CLIENT_ID) i
ON f.CLIENT_ID = i.CLIENT_ID
AND f.RECEIVED_DATE = i.MaxRecDate) b
ON a.ACCESSION_DAILY_KEY = b.ACCESSION_DAILY_KEY),
cte_est
AS (SELECT DISTINCT client_id,
MLIS_DATE_ESTABLISHED
FROM D_CLIENT
WHERE REC_ACTIVE_FLG = 1
AND MLIS_DATE_ESTABLISHED IS NOT NULL)
SELECT DISTINCT f.client_id,
cmin.specimen_source,
cmin.received_date,
cmax.specimen_source,
cmax.received_date,
cest.MLIS_DATE_ESTABLISHED
FROM F_ACCESSION_DAILY f
LEFT JOIN cte_max cmax
ON cmax.CLIENT_ID = f.CLIENT_ID
LEFT JOIN cte_min cmin
ON cmin.CLIENT_ID = f.CLIENT_ID
LEFT JOIN cte_est cest
ON cest.CLIENT_ID = f.CLIENT_ID
我并不是要求你自己进行简化(虽然我会非常感激),而是我要求重新编写此查询的一般指导方针/指示更优雅。
答案 0 :(得分:3)
这看起来更好吗?
;WITH minmax AS (
SELECT client_id, specimen_source, received_date,
RMin = row_number() over (partition by Client_id
order by received_date, accession_daily_key),
RMax = row_number() over (partition by Client_id
order by received_date desc, accession_daily_key desc)
FROM F_ACCESSION_DAILY
)
SELECT f.client_id,
max(case when rmin=1 then f.specimen_source end),
max(case when rmin=1 then f.received_date end),
max(case when rmax=1 then f.specimen_source end),
max(case when rmax=1 then f.received_date end),
D.MLIS_DATE_ESTABLISHED
FROM minmax f
LEFT JOIN D_CLIENT D ON D.REC_ACTIVE_FLG = 1 AND D.MLIS_DATE_ESTABLISHED IS NOT NULL
WHERE 1 in (f.rmin, f.rmax)
GROUP BY f.client_id, D.MLIS_DATE_ESTABLISHED
答案 1 :(得分:1)
50行报告5个值,并且在所有这些中仅引用了两个表。
在第一个CTE中,您有4个连接(或虚拟连接)到同一个表,没有其他表涉及报告3列。不知道关键所以不能得出结论可以减少。
如果cte不是多次引用,那么它不会导致更少的代码行。
对于其中一个,这个cte可以用更少的代码替换。
cte_est
AS (SELECT DISTINCT client_id,
MLIS_DATE_ESTABLISHED
FROM D_CLIENT
WHERE REC_ACTIVE_FLG = 1
AND MLIS_DATE_ESTABLISHED IS NOT NULL)
...
cest.MLIS_DATE_ESTABLISHED
...
LEFT JOIN cte_est cest
ON cest.CLIENT_ID = f.CLIENT_ID
缩减为
D_CLIENT.MLIS_DATE_ESTABLISHED
...
LEFT JOIN D_CLIENT
ON D_CLIENT.CLIENT_ID = f.CLIENT_ID
AND D_CLIENT.REC_ACTIVE_FLG = 1
AND D_CLIENT.MLIS_DATE_ESTABLISHED IS NOT NULL
答案 2 :(得分:1)
虽然我不确定每个人是否会认为这更简单和/或更容易阅读,但我会这样做:
WITH
cte_MaxMinRecvd As
(
SELECT CLIENT_ID,
Min(received_date) MinRecDate,
Max(received_date) MaxRecDate
FROM F_ACCESSION_DAILY
GROUP BY CLIENT_ID
)
, cte_MaxMinDaily As
(
SELECT *
FROM F_ACCESSION_DAILY f
JOIN cte_MaxMinRecvd i ON f.CLIENT_ID = i.CLIENT_ID
)
, cte_min AS
(
SELECT a.client_id,
a.specimen_source,
a.received_date
FROM F_ACCESSION_DAILY a
WHERE EXISTS(
SELECT *
FROM cte_MaxMinDaily f
WHERE f.RECEIVED_DATE = f.MinRecDate
AND a.ACCESSION_DAILY_KEY = f.ACCESSION_DAILY_KEY
)
)
, cte_max AS
(
SELECT a.client_id,
a.specimen_source,
a.received_date
FROM f_accession_daily a
WHERE EXISTS(
SELECT *
FROM cte_MaxMinDaily f
WHERE f.RECEIVED_DATE = f.MinRecDate
AND a.ACCESSION_DAILY_KEY = f.ACCESSION_DAILY_KEY
)
)
SELECT DISTINCT
f.client_id,
cmin.specimen_source,
cmin.received_date,
cmax.specimen_source,
cmax.received_date,
cest.MLIS_DATE_ESTABLISHED
FROM F_ACCESSION_DAILY f
LEFT JOIN cte_max cmax ON cmax.CLIENT_ID = f.CLIENT_ID
LEFT JOIN cte_min cmin ON cmin.CLIENT_ID = f.CLIENT_ID
LEFT JOIN D_CLIENT cest ON cest.CLIENT_ID = f.CLIENT_ID
AND cest.REC_ACTIVE_FLG = 1
AND cest.MLIS_DATE_ESTABLISHED IS NOT NULL
主要是我做的是
哎呀,我也摆脱了Blam建议的cte_est CTE。