Sql server 比较历史行(滞后行)并将更改的值合并到单个列

Sql server 比较历史行(滞后行)并将更改的值合并到单个列,sql-server,tsql,sql-server-2016,Sql Server,Tsql,Sql Server 2016,比较历史行(基于ResultChngDt的滞后行)并将更改的列值合并到单个列。正在寻找有关编写优雅/高效的SQL Server 2016 TSQL代码(无光标)的帮助 我有一个表,其结构和数据如下: +----+-------+--------------+---------------+--------+--------+--------------+ | ID | RepID | CollctedDate | CompletedDate | Result | Tcode | ResultC

比较历史行(基于ResultChngDt的滞后行)并将更改的列值合并到单个列。正在寻找有关编写优雅/高效的SQL Server 2016 TSQL代码(无光标)的帮助

我有一个表,其结构和数据如下:

+----+-------+--------------+---------------+--------+--------+--------------+
| ID | RepID | CollctedDate | CompletedDate | Result | Tcode  | ResultChngDt |
+----+-------+--------------+---------------+--------+--------+--------------+
| 1  | 101   | 11/20/2017   | 12/13/2017    |        | L-2190 | 12/13/2017   |
| 1  | 101   | 11/22/2017   | 12/15/2017    | POS    | L-Afb  | 1/5/2018     |
| 1  | 102   | 11/22/2017   | 12/15/2017    |        | L-2191 | 12/15/2017   |
| 1  | 102   | 11/22/2017   | 12/15/2017    | POS    | L-2192 | 12/31/2017   |
+----+-------+--------------+---------------+--------+--------+--------------+
我需要生成一份报告/结果,如下所示:

+----+-------+---------------------------+--------------------------+--+
| ID | RepID | Previous                  | Current                  |  |
+----+-------+---------------------------+--------------------------+--+
| 1  | 101   | CollctedDate:11/20/2017   | CollctedDate:11/22/2017  |  |
|    |       | CompletedDate:12/13/2017  | CompletedDate:12/15/2017 |  |
|    |       | Result:                   | Result:POS               |  |
|    |       | Tcode:L-2190              | Tcode:L-Afb              |  |
| 1  | 102   | CollctedDate:11/22/2017   | CollctedDate:11/22/2017  |  |
|    |       | CompletedDate:12/15/2017  | CompletedDate:12/15/2017 |  |
|    |       | Result:                   | Result:POS               |  |
|    |       | Tcode:L-2191              | Tcode:L-2192             |  |
+----+-------+---------------------------+--------------------------+--+

CREATE TABLE [dbo].[Table1]
    (
        [ID]            INT         NULL,
        [RepID]         INT         NULL,
        [CollctedDate]  DATETIME    NULL,
        [CompletedDate] DATETIME    NULL,
        [Result]        VARCHAR(3)  NULL,
        [Tcode]         VARCHAR(10) NULL,
        [ResultChngDt]  DATETIME    NULL
    ) ON [PRIMARY];
GO

INSERT INTO [dbo].[Table1] ([ID], [RepID], [CollctedDate], [CompletedDate], [Result], [Tcode], [ResultChngDt])
 VALUES (1, 101, N'11/20/2017', N'12/13/2017', N'', N'L-2190', N'12/13/2017') 
, (1, 101, N'11/22/2017', N'12/15/2017', N'POS', N'L-Afb', N'1/5/2018') 
, (1, 102, N'11/22/2017', N'12/15/2017', N'', N'L-2191', N'12/15/2017') 
, (1, 102, N'11/22/2017', N'12/15/2017', N'POS', N'L-2192', N'12/31/2017') 

以下是我对你的问题的疑问:

    WITH cte_LEADLAG AS(
    SELECT ID,
           RepID,
           CollctedDate,
           CompletedDate,
           Result,
           Tcode,
           ResultChngDt,
           CONCAT('CollectedDate:',CAST(CollctedDate AS DATETIME2), ' CompletedDate:', CAST(CompletedDate AS DATETIME2), ' Result:', Result, ' Tcode', Tcode) AS dates,
           LAG(CollctedDate) OVER(PARTITION BY RepID ORDER BY CollctedDate) AS 'LAGCollectedDate'  ,
           lead(CollctedDate) OVER(PARTITION BY RepID ORDER BY CollctedDate) AS 'LEADCollectedDate',
           LAG(CompletedDate) OVER(PARTITION BY RepID ORDER BY CompletedDate) AS 'LAGCompDate'  ,
           lead(CompletedDate) OVER(PARTITION BY RepID ORDER BY CompletedDate) AS 'LEADcompDate' ,
           LEAD(Result) OVER(PARTITION BY RepID ORDER BY CompletedDate) AS 'LEADResult' ,
           LEAD(Tcode) OVER(PARTITION BY RepID ORDER BY CompletedDate) AS 'LEADTcode'    
    FROM #temp
    ),
     cte_FINAL AS(
    SELECT distinct ID,
                    RepID,
                    CASE WHEN cte.LAGCollectedDate IS NULL THEN CONCAT('CollectedDate:',CAST(CollctedDate AS DATETIME2), ' CompletedDate:', CAST(CompletedDate AS DATETIME2), ' Result:', Result, ' Tcode', Tcode) end AS 'Previous',
                    CASE WHEN cte.LEADCollectedDate IS not NULL THEN  CONCAT('CollectedDate:',CAST(cte.LEADCollectedDate AS DATETIME2), ' CompletedDate:', CAST(LEADcompDate AS DATETIME2), ' Result:', cte.LEADResult, ' Tcode', cte.LEADTcode) end AS 'Current'
    FROM cte_LEADLAG AS cte
    WHERE cte.LEADCollectedDate IN (SELECT MAX(LEADCollectedDate) FROM cte_LEADLAG WHERE cte_LEADLAG.RepID = cte.RepID))
)
    SELECT *
    FROM cte_FINAL;
结果:


这将在一行中提供所需的所有数据。您可以处理报表格式设置,以满足您在使用的任何工具中的任何要求。

请将数据作为可消费SQL(创建表,然后插入到)发布,以及您到目前为止的查询请提供创建表和插入示例数据的查询。此外,请根据样本数据提供要求的结果,也可以说生成“报告”。在什么地方?SSR?PowerBI?还有别的吗?到目前为止,您尝试了什么?虽然我已经在so中发布了问题,但我对这里的发布表结构和代码是新的。对不起,桌子太乱了。我正在为表脚本提供insert语句。@Larnu,如果这看起来像是你的家庭作业,我相信你有更好的解决方案,请提供我如何解决这个问题的想法。“报告”可以是SSRS/PowerBI,与我的问题中提供的表2挂钩。谢谢Samita的回答和逻辑。这是有效的,很抱歉,所以不允许我为你的答案投票!当我投票时,它发出的信息是,声誉低于15的人所投的票会被记录下来,但不会公开改变。这里还有一些自称“无所不知”的金牌志愿者在问题上投了反对票,其中一个在这里失去了声誉!再次感谢,我宣布你是SO的“金牌”类志愿者。好吧,到时候你会得到15分,并获得投票许可,同时你做了我认为最好的行动,那就是说谢谢。。。A感谢等于1000分
:-)
顺便说一句,我很高兴看到你得到了一个适合你的答案,在你添加了创建表和插入样本数据的查询之后,我没有很快回来
with data as (
    select *, row_number() over (partition by RepID order by ResultChgDt desc) as rn
    from dbo.Table1
)
select
from data as d1 left outer join data as d2 on d2.rn = d1.rn + 1
where d1.rn = 1 -- I suppose you only want the two most recent??