【问题标题】:SQL - Get fall back values if no data is availableSQL - 如果没有可用数据,则获取回退值
【发布时间】:2020-02-05 20:05:42
【问题描述】:

我有一个表 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 

谁能告诉我如何才能得到这个结果?

【问题讨论】:

  • 是您从查询中得到的结果,还是您想要从查询中得到的结果..?
  • 更新了我正在寻找的预期结果,而不是 NULL 值,我正在寻找 2016-09-30 的后备值,这是 TBL_B 中的最后一个可用值

标签: sql sql-server-2008 select where-clause fallback


【解决方案1】:

一种方法是:

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

【讨论】:

  • 它们中的任何一个都不起作用,第一个查询导致的行数超过了我正在寻找的 6 个结果,第二个查询出错了。有什么帮助吗?
【解决方案2】:

这是对我有用的查询

  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;

【讨论】:

    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多