根据同一日期合并行?

时间:2018-01-22 11:07:07

标签: sql-server

我的表格如下所示

Date             | ID   | Period | ArchivedBy | ArchivedFlag | Value
2018-01-20 12:23 |23344 |  Q1    |  NULL      |   NULL       | 200
2018-01-20 12:20 |23344 |  NULL  |  P.Tills   |   1          | NULL
2018-01-20 12:19 |23344 |  NULL  |  NULL      |   1          | NULL

此表表示对协议所做的所有编辑(每个新编辑都有自己的行)。如果一个值根本没有改变,它会说是NULL。

理想情况下,上面的内容如下所示

Date             | ID   | Period | ArchivedBy | ArchivedFlag | Value
2018-01-20       |23344 |  Q1    |  P.Tills   |   1          | 200

此返回的行应根据日期显示协议的最新状态。因此,对于我的示例(2018-01-20)中的日期,将返回此一行,将一天中所做的所有更改合并为一行,以显示它在一天中所有更改后的外观。

我希望这有道理吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

以下是使用Row_NumberGroup by

的一种方法
SELECT [Date] = Cast([Date] AS DATE),
       ID,
       Max(period),
       Max(ArchivedBy),
       Max(ArchivedFlag),
       Max(CASE WHEN rn = 1 THEN [Value] END)
FROM   (SELECT *,
               Rn = Row_number()OVER(partition BY Cast([Date] AS DATE), ID ORDER BY [Date] DESC)
        FROM   Yourtable)a
GROUP  BY Cast([Date] AS DATE),
          ID 

答案 1 :(得分:0)

我会提出2个解决方案。

<强>简单

每天选择top 1 NOT NULL值:

SELECT G.ID, G.GD Date, Period.*, ArchivedBy.*, Value.* FROM
(SELECT DISTINCT ID, CAST(Date AS Date) GD FROM T) G
CROSS APPLY (SELECT TOP 1 Period FROM T WHERE Period IS NOT NULL AND CAST(Date AS Date)=GD ORDER BY Date DESC) Period
CROSS APPLY (SELECT TOP 1 ArchivedBy FROM T WHERE ArchivedBy IS NOT NULL AND CAST(Date AS Date)=GD ORDER BY Date DESC) ArchivedBy
CROSS APPLY (SELECT TOP 1 Value FROM T WHERE Value IS NOT NULL AND CAST(Date AS Date)=GD ORDER BY Date DESC) Value

优化(直观,未经测试*)

使用varbinary排序规则和聚合,手动命令NULL:

SELECT CAST(Date AS Date), ID,
  CAST(SUBSTRING(MAX(Arch),9, LEN(MAX(Arch))) AS varchar(10)) ArchivedBy --unbox
  --other columns
  FROM
(
    SELECT Date, ID,
        CAST(CASE WHEN ArchivedBy IS NOT NULL THEN ROW_NUMBER() OVER (PARTITION BY CAST(Date AS Date) ORDER BY Date) ELSE 0 END AS varbinary(MAX))+CAST(ArchivedBy AS varbinary(MAX)) Arch --box
        --other columns
    FROM T
) Tab
GROUP BY ID, CAST(Date AS Date)