【问题标题】:SQL Server Joining record based on max 7 days old基于最长 7 天的 SQL Server 加入记录
【发布时间】:2017-01-13 16:00:09
【问题描述】:

我构建的查询不适合解决方案。我尝试了很多查询,但无法得到我想要的结果。

我有下表

    CREATE TABLE [dbo].[test](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ATC] [varchar](15) NOT NULL,
    [PID] [varchar](7) NOT NULL,
    [NAME] [varchar](50) NOT NULL,
    [REG_DATE] [datetime] NULL,
    [ACTIVE] [bit] NOT NULL CONSTRAINT [DF_test_ACTIVE]  DEFAULT ((1))
) ON [PRIMARY]

示例数据

  INSERT INTO [dbo].[test] ([ATC],[PID],[NAME],[REG_DATE],[ACTIVE])
  VALUES ('A01','123456','TEST1','2016-08-31 00:00:00.000',0);
  INSERT INTO [dbo].[test] ([ATC],[PID],[NAME],[REG_DATE],[ACTIVE])
  VALUES ('A01','123456','TEST2','2016-09-01 00:00:00.000',0);
  INSERT INTO [dbo].[test] ([ATC],[PID],[NAME],[REG_DATE],[ACTIVE])
  VALUES ('A01','123456','TEST3','2016-09-02 00:00:00.000',0);
  INSERT INTO [dbo].[test] ([ATC],[PID],[NAME],[REG_DATE],[ACTIVE])
  VALUES ('A01','123456','TEST4','2016-09-03 00:00:00.000',0);
  INSERT INTO [dbo].[test] ([ATC],[PID],[NAME],[REG_DATE],[ACTIVE])
  VALUES('A01','123456','TEST5','2016-09-06 00:00:00.000',1);

示例查询:

;WITH CTE AS
(
    SELECT ROW_NUMBER() OVER (PARTITION BY ATC, PID ORDER BY REG_DATE ASC) AS ROWNUM,* FROM [dbo].[test]
    WHERE ACTIVE=0
)
SELECT DATEDIFF(DAY, d2.REG_DATE, d1.REG_DATE),d1.NAME, d1.REG_DATE AS ACTIVE_REC_DATE, d2.REG_DATE AS NOTACTIVE_REC_DATE, d1.ACTIVE, d2.ACTIVE FROM [dbo].[test] as d1
LEFT JOIN CTE d2 ON d2.ATC = d1.ATC AND d2.PID = d1.PID
AND DATEDIFF(DAY, d2.REG_DATE, d1.REG_DATE) <= 7
WHERE d1.ACTIVE=1 AND d1.PID=123456;

想要的结果:

列 ACTIVE True (1) 的记录应包含(如果记录存在)不活动的先前记录的 REG_DATE,最长 7 天。喜欢:

(No column name)    NAME    ACTIVE_REC_DATE NOTACTIVE_REC_DATE  ACTIVE  ACTIVE
3   TEST5   2016-09-06 00:00:00.000 2016-08-31 00:00:00.000 1   0

目前查询结果包含多条记录,因为更多的记录将落在 7 天的时间段内。我需要加入 1 条最长 7 天的记录。

我使用了 ROW_NUMBER() 和 over partition by,所以我可以使用和识别第一条记录,因为我将按升序排序。当没有可用的以前记录或以前的记录超过 7 天时,这不起作用 当没有要加入的记录被忽略时,可以使用 INNER JOIN 或 null 处的日期列

我希望我的解释清楚。

【问题讨论】:

  • 能否请您也发布您的预期结果表
  • 您能解释一下“当没有可用的以前记录或以前的记录超过 7 天时,这不起作用”? - 在这种情况下结果应该是什么?
  • @SandipPatel 预期的结果也在我的解释中。它低于通缉结果:

标签: sql-server


【解决方案1】:
SELECT DATEDIFF(DAY, d2.REG_DATE, d1.REG_DATE),d1.NAME, d1.REG_DATE AS ACTIVE_REC_DATE, d2.REG_DATE AS NOTACTIVE_REC_DATE, d1.ACTIVE, d2.ACTIVE FROM [dbo].[test] as d1
OUTER APPLY 
(SELECT TOP 1 T1.* FROM dbo.test t1 WHERE t1.ATC = d1.ATC AND t1.PID = d1.PID and DATEDIFF(DAY, t1.REG_DATE, d1.REG_DATE) <= 7 order by t1.REG_DATE desc) d2
WHERE d1.ACTIVE=1 AND d1.PID=123456;

【讨论】:

  • 我需要将排序顺序更改为升序以获得想要的结果。查询似乎有效,但我需要检查某些情况。谢谢你的时间。以前从未使用过 APPLY。
  • 我不确定您是否需要最旧的日期或最新的日期,但我很高兴到目前为止它对您有所帮助。
【解决方案2】:

您可以通过将ROWNUM 上的过滤器添加到您的左连接来为PID 返回单行:

;WITH CTE AS
(
    SELECT ROW_NUMBER() OVER (PARTITION BY ATC, PID ORDER BY REG_DATE ASC) AS ROWNUM,* FROM [dbo].[test]
    WHERE ACTIVE=0
)
SELECT DATEDIFF(DAY, d2.REG_DATE, d1.REG_DATE),d1.NAME, d1.REG_DATE AS ACTIVE_REC_DATE, d2.REG_DATE AS NOTACTIVE_REC_DATE, d1.ACTIVE, d2.ACTIVE FROM [dbo].[test] as d1
LEFT JOIN CTE d2 ON d2.ATC = d1.ATC AND d2.PID = d1.PID
AND DATEDIFF(DAY, d2.REG_DATE, d1.REG_DATE) <= 7
AND d2.ROWNUM = 1
WHERE d1.ACTIVE=1 AND d1.PID=123456;

当过去 7 天的先前记录不存在时,查询的行为方式并不清楚。

【讨论】:

  • 在这种情况下,连接的列将为空。
  • 在寻找解决方案时,我做了一些测试场景,rownum 1 并不总是正确的行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-02
  • 2019-07-15
  • 2018-11-16
  • 1970-01-01
相关资源
最近更新 更多