检查每个实体是否在两年内报告

时间:2020-09-18 02:52:25

标签: sql-server tsql

不确定如何以优雅的方式执行此操作。 我需要创建一个向我显示的变量,作为两年一次的审计报告是否按时发生:ON_TIME: (yes - no. In the dummy dateset below, I can only refer to ON_TIME :(是的-否)如果我要进行比较连续日期的ID,因为我拥有从2016年到今天的数据,如何确定比较正确的对? 你会排名第一吗?怎么样?

在下面的示例中,ON_TIME应该显示:

ID       ON_TIME 
11356   yes
489734  yes
9458    no

SELECT '11356' AS ID, '2016-06-15' AS Audit_Date, (DATEADD(DAY,730,'2016-06-15')) AS Next_Audit_Due
UNION
SELECT '9458' AS ID, '2018-05-12' AS Audit_Date , (DATEADD(DAY,730,'2018-05-12')) AS Next_Audit_Due
UNION
SELECT '489734' AS ID, '2017-12-01'  AS Audit_Date, (DATEADD(DAY,730,'2017-12-01')) AS Next_Audit_Due
UNION
SELECT '11356' AS ID, '2018-06-15' AS Audit_Date, (DATEADD(DAY,730,'2016-06-15')) AS Next_Audit_Due
UNION
SELECT '9458' AS ID, '2020-08-12' AS Audit_Date , (DATEADD(DAY,730,'2018-05-12')) AS Next_Audit_Due
UNION
SELECT '489734' AS ID, '2019-11-31'  AS Audit_Date, (DATEADD(DAY,730,'2017-12-01')) AS Next_Audit_Due 

我想创建一个名为“ on_time”的新变量,该变量显示是否在en实体(ID)进行上次审核(Audit_date)的两年内进行了审核。如果可能的话,我不想转置数据集。实体(ID)需要相互保留。

2 个答案:

答案 0 :(得分:1)

我不确定您是要返回所有行还是仅返回最新行。无论如何,使用LAG的此解决方案都可以。

也不清楚Next_Audit_Due与问题的关系。

WITH TestData AS (
    SELECT '11356' AS ID, '2016-06-15' AS Audit_Date, (DATEADD(DAY,730,'2016-06-15')) AS Next_Audit_Due
    UNION
    SELECT '9458' AS ID, '2018-05-12' AS Audit_Date , (DATEADD(DAY,730,'2018-05-12')) AS Next_Audit_Due
    UNION
    SELECT '489734' AS ID, '2017-12-01'  AS Audit_Date, (DATEADD(DAY,730,'2017-12-01')) AS Next_Audit_Due
    UNION
    SELECT '11356' AS ID, '2018-06-15' AS Audit_Date, (DATEADD(DAY,730,'2016-06-15')) AS Next_Audit_Due
    UNION
    SELECT '9458' AS ID, '2020-08-12' AS Audit_Date , (DATEADD(DAY,730,'2018-05-12')) AS Next_Audit_Due
    UNION
    SELECT '489734' AS ID, '2019-11-30'  AS Audit_Date, (DATEADD(DAY,730,'2017-12-01')) AS Next_Audit_Due
)
SELECT ID, Audit_Date, Next_Audit_Due
  , CASE WHEN Lagged_Audit_Date IS NULL THEN 'N/A' WHEN DATEADD(YEAR, 2, Lagged_Audit_Date) >= Audit_Date THEN 'Yes' ELSE 'No' END [ON_TIME]
FROM (
  SELECT id, CONVERT(DATE, Audit_Date, 23) Audit_Date, Next_Audit_Due
    , LAG(Audit_Date) OVER (PARTITION BY ID ORDER BY Audit_Date ASC) Lagged_Audit_Date
    , ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Audit_Date DESC) RowNumber
  FROM TestData
) X
-- Comment out to only show the latest row per ID
-- WHERE RowNumber = 1
ORDER BY id, Audit_Date ASC;

返回:

ID      Audit_Date  Next_Audit_Due          ON_TIME
11356   2016-06-15  2018-06-15 00:00:00.000 N/A
11356   2018-06-15  2018-06-15 00:00:00.000 Yes
489734  2017-12-01  2019-12-01 00:00:00.000 N/A
489734  2019-11-30  2019-12-01 00:00:00.000 Yes
9458    2018-05-12  2020-05-11 00:00:00.000 N/A
9458    2020-08-12  2020-05-11 00:00:00.000 No

正如史蒂夫所说,那里有一个无效的日期...

答案 1 :(得分:0)

看来这符合要求

数据

drop table if exists #ontime;
go
with data as (
SELECT '11356' AS ID, '2016-06-15' AS Audit_Date, (DATEADD(DAY,730,'2016-06-15')) AS Next_Audit_Due
UNION
SELECT '9458' AS ID, '2018-05-12' AS Audit_Date , (DATEADD(DAY,730,'2018-05-12')) AS Next_Audit_Due
UNION
SELECT '489734' AS ID, '2017-12-01'  AS Audit_Date, (DATEADD(DAY,730,'2017-12-01')) AS Next_Audit_Due
UNION
SELECT '11356' AS ID, '2018-06-15' AS Audit_Date, (DATEADD(DAY,730,'2016-06-15')) AS Next_Audit_Due
UNION
SELECT '9458' AS ID, '2020-08-12' AS Audit_Date , (DATEADD(DAY,730,'2018-05-12')) AS Next_Audit_Due
UNION
SELECT '489734' AS ID, '2019-12-01'  AS Audit_Date, (DATEADD(DAY,730,'2017-12-01')) AS Next_Audit_Due )
select id, Audit_Date, Next_Audit_Due
into #ontime
from data;

查询

select id, max(case when cast(Audit_Date as date)=cast(Next_Audit_Due as date) then 1 else 0 end) on_time
from #ontime
group by id;

输出

id      on_time
11356   1
489734  1
9458    0