SQL - 如果没有可用数据则获取回退值
SQL - Get fall back values if no data is available
我有一个 table TBL_A 喜欢:
CLASS_ID PERIOD_DT MAX_DT
-----------------------------------
358614 2018-09-30 2018-09-30
358614 2017-09-30 2018-09-30
358614 2016-09-30 2018-09-30
358614 2015-09-30 2018-09-30
358614 2014-09-30 2018-09-30
358614 2013-09-30 2018-09-30
和TBL_B喜欢:
CLASS_ID CLASS_DT
----------------------
358614 2018-09-30
358614 2017-09-30
358614 2016-09-30
我正在尝试使用 CLASS_DT 获取过去六年的结果集,但有些 类 没有足够的信息。如果日期不可用,我需要使用接近当前期间日期的先前可用数据。所以我的最终结果应该是这样的
预期结果:
PERIOD_DT FALLBACK_CLASS_DT
-------------------------------
2018-09-30 2018-09-30
2017-09-30 2017-09-30
2016-09-30 2016-09-30
2015-09-30 2016-09-30 // fallback dates, since they are not available
2014-09-30 2016-09-30
2013-09-30 2016-09-30
我正在尝试的查询是:
SELECT A.PERIOD_DT,
(SELECT TOP 1 CAST(B.CLASS_DT AS DATE)
FROM TBL_B AS B
WHERE B.CLASS_ID = A.CLASS_ID
AND CAST(B.CLASS_DT AS DATE) <= CAST(A.PERIOD_DT AS DATE)
AND CAST(A.PERIOD_DT AS DATE) <= CAST(A.MAX_DT AS DATE)
ORDER BY B.CLASS_DT DESC) AS FALLBACK_CLASS_DT
FROM TBL_A AS A
WHERE A.CLASS_ID = 358614
ORDER BY A.PERIOD_DT DESC;
我得到的结果是:
PERIOD_DT FALLBACK_CLASS_DT
-------------------------------
2018-09-30 2018-09-30
2017-09-30 2017-09-30
2016-09-30 2016-09-30
2015-09-30 NULL
2014-09-30 NULL
2013-09-30 NULL
谁能告诉我怎样才能得到这个结果?
一种方法是:
select a.*, coalesce(b.class_dt, bdef.class_dt)
from tbl_a a left join
tbl_b b
on b.CLASS_ID = a.CLASS_ID and
b.class_dt >= a.period_dt and
b.class_dt <= a.max_dt left join
(select b.class_id, min(b.period_dt) as class_dt
from tbl_b
group by b.class_id
) bdef
on bdef.class_id = a.class_id;
我想你也可以使用 outer apply
:
select a.*, b.class_dt
from tbl_a a left join
(select top (1) b.*
from tbl_b b
where b.CLASS_ID = a.CLASS_ID and
b.class_dt <= a.max_dt
order by b.period_dt desc
) b
这是对我有用的查询
SELECT
A.CLASS_ID,
A.PERIOD_DT,
ISNULL((SELECT TOP 1 CAST(B.CLASS_DT AS DATE)
FROM TBL_B AS B
WHERE B.CLASS_ID = A.CLASS_ID
AND CAST(B.CLASS_DT AS DATE) <= CAST(A.PERIOD_DT AS DATE)
AND CAST(A.PERIOD_DT AS DATE) <= CAST(A.MAX_DT AS DATE)
ORDER BY B.CLASS_DT DESC
), B2.CLASS_DT) AS FALLBACK_CLASS_DT
FROM TBL_A AS A
LEFT JOIN (SELECT B.CLASS_ID, MIN(B.CLASS_DT) AS CLASS_DT
FROM TBL_B AS B
GROUP BY B.CLASS_ID) AS B2 ON B2.CLASS_ID = A.CLASS_ID
WHERE A.CLASS_ID = 358614
ORDER BY A.PERIOD_DT DESC;
我有一个 table TBL_A 喜欢:
CLASS_ID PERIOD_DT MAX_DT
-----------------------------------
358614 2018-09-30 2018-09-30
358614 2017-09-30 2018-09-30
358614 2016-09-30 2018-09-30
358614 2015-09-30 2018-09-30
358614 2014-09-30 2018-09-30
358614 2013-09-30 2018-09-30
和TBL_B喜欢:
CLASS_ID CLASS_DT
----------------------
358614 2018-09-30
358614 2017-09-30
358614 2016-09-30
我正在尝试使用 CLASS_DT 获取过去六年的结果集,但有些 类 没有足够的信息。如果日期不可用,我需要使用接近当前期间日期的先前可用数据。所以我的最终结果应该是这样的
预期结果:
PERIOD_DT FALLBACK_CLASS_DT
-------------------------------
2018-09-30 2018-09-30
2017-09-30 2017-09-30
2016-09-30 2016-09-30
2015-09-30 2016-09-30 // fallback dates, since they are not available
2014-09-30 2016-09-30
2013-09-30 2016-09-30
我正在尝试的查询是:
SELECT A.PERIOD_DT,
(SELECT TOP 1 CAST(B.CLASS_DT AS DATE)
FROM TBL_B AS B
WHERE B.CLASS_ID = A.CLASS_ID
AND CAST(B.CLASS_DT AS DATE) <= CAST(A.PERIOD_DT AS DATE)
AND CAST(A.PERIOD_DT AS DATE) <= CAST(A.MAX_DT AS DATE)
ORDER BY B.CLASS_DT DESC) AS FALLBACK_CLASS_DT
FROM TBL_A AS A
WHERE A.CLASS_ID = 358614
ORDER BY A.PERIOD_DT DESC;
我得到的结果是:
PERIOD_DT FALLBACK_CLASS_DT
-------------------------------
2018-09-30 2018-09-30
2017-09-30 2017-09-30
2016-09-30 2016-09-30
2015-09-30 NULL
2014-09-30 NULL
2013-09-30 NULL
谁能告诉我怎样才能得到这个结果?
一种方法是:
select a.*, coalesce(b.class_dt, bdef.class_dt)
from tbl_a a left join
tbl_b b
on b.CLASS_ID = a.CLASS_ID and
b.class_dt >= a.period_dt and
b.class_dt <= a.max_dt left join
(select b.class_id, min(b.period_dt) as class_dt
from tbl_b
group by b.class_id
) bdef
on bdef.class_id = a.class_id;
我想你也可以使用 outer apply
:
select a.*, b.class_dt
from tbl_a a left join
(select top (1) b.*
from tbl_b b
where b.CLASS_ID = a.CLASS_ID and
b.class_dt <= a.max_dt
order by b.period_dt desc
) b
这是对我有用的查询
SELECT
A.CLASS_ID,
A.PERIOD_DT,
ISNULL((SELECT TOP 1 CAST(B.CLASS_DT AS DATE)
FROM TBL_B AS B
WHERE B.CLASS_ID = A.CLASS_ID
AND CAST(B.CLASS_DT AS DATE) <= CAST(A.PERIOD_DT AS DATE)
AND CAST(A.PERIOD_DT AS DATE) <= CAST(A.MAX_DT AS DATE)
ORDER BY B.CLASS_DT DESC
), B2.CLASS_DT) AS FALLBACK_CLASS_DT
FROM TBL_A AS A
LEFT JOIN (SELECT B.CLASS_ID, MIN(B.CLASS_DT) AS CLASS_DT
FROM TBL_B AS B
GROUP BY B.CLASS_ID) AS B2 ON B2.CLASS_ID = A.CLASS_ID
WHERE A.CLASS_ID = 358614
ORDER BY A.PERIOD_DT DESC;