sql - 按日期为多行中的每一列选择第一个非空值

标签 sql sql-server tsql sql-server-2008 null

我有如下表格:

+-------------------------+------+------+------+------+  
|          Date           |  A   |  B   |  C   |  D   |  
+-------------------------+------+------+------+------+  
| 2010-11-16 10:02:00.000 | 10   | NULL | NULL | NULL |  
| 2010-09-21 00:00:00.000 | 86   | 14   | NULL | 17   |  
| 2010-07-27 00:00:00.000 | 125  | 12   | NULL | 11   |  
| 2010-05-29 15:24:00.000 | NULL | NULL | 1250 | NULL |  
+-------------------------+------+------+------+------+  

我需要一个查询来提取每列的第一个非空值。某种“垂直合并”。

期望的结果是:

+-------------------------+------+------+------+------+  
|          Date           |  A   |  B   |  C   |  D   |  
+-------------------------+------+------+------+------+  
| 2010-11-16 10:02:00.000 | 10   | 14   | 1250 | 17   |  
+-------------------------+------+------+------+------+ 

表格按日期排序(desc)
实际表格有更多的列(40)和行(最多 5000)

编辑:

我的实际表格有更多的列和行(比如说大约 40 列和最多 5000 行)。我担心多个 order-by 查询会降低查询的性能。但是,如果没有更清洁的解决方案出现,我会继续努力。

最佳答案

这是一种可能的方法,如果您的订单按 [Date] 列降序:

输入:

CREATE TABLE #Table (
    [Date] datetime,
    A int,
    B int,
    C int,
    D int
)
INSERT INTO #Table
    ([Date], A, B, C, D)
VALUES
    ('2010-11-16T10:02:00.000', 10  , NULL, NULL, NULL),  
    ('2010-09-21T00:00:00.000', 86  , 14  , NULL, 17  ),  
    ('2010-07-27T00:00:00.000', 125 , 12  , NULL, 11  ),  
    ('2010-05-29T15:24:00.000', NULL, NULL, 1250, NULL)  

声明:

SELECT 
    [Date] = (SELECT TOP 1 [Date] FROM #Table WHERE [Date] IS NOT NULL ORDER BY [Date] DESC),
    [A] = (SELECT TOP 1 [A] FROM #Table WHERE [A] IS NOT NULL ORDER BY [Date] DESC),
    [B] = (SELECT TOP 1 [B] FROM #Table WHERE [B] IS NOT NULL ORDER BY [Date] DESC),
    [C] = (SELECT TOP 1 [C] FROM #Table WHERE [C] IS NOT NULL ORDER BY [Date] DESC),
    [D] = (SELECT TOP 1 [D] FROM #Table WHERE [D] IS NOT NULL ORDER BY [Date] DESC)

输出:

Date                    A   B   C       D
2010-11-16 10:02:00.000 10  14  1250    17

更新 - 另一种可能的方法,使用聚合函数:

;WITH DatesCTE AS (
    SELECT
        [Date] = MAX([Date]), 
        [DateA] = MAX(CASE WHEN A IS NOT NULL THEN [Date] END),
        [DateB] = MAX(CASE WHEN B IS NOT NULL THEN [Date] END),
        [DateC] = MAX(CASE WHEN C IS NOT NULL THEN [Date] END),
        [DateD] = MAX(CASE WHEN D IS NOT NULL THEN [Date] END)
    FROM #Table
)
SELECT 
    d.[Date],
    A = MAX(CASE WHEN t.[Date] = d.[DateA] THEN A END),
    B = MAX(CASE WHEN t.[Date] = d.[DateB] THEN B END),
    C = MAX(CASE WHEN t.[Date] = d.[DateC] THEN C END),
    D = MAX(CASE WHEN t.[Date] = d.[DateD] THEN D END)
FROM DatesCTE d
CROSS APPLY #Table t
GROUP BY d.[Date]

关于sql - 按日期为多行中的每一列选择第一个非空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54572706/

相关文章:

java - HQL不返回结果,但直接查询时它可以工作

mysql - SQL - 我想要选择 - 并更新所选

sql - SQL Server 2005中如何在列中存储超过8000个字符?

SQL MAX 多列?

sql - 添加特殊约束以避免出现这种情况的重复行?

sql - 如何查找给定列是否存在唯一键约束

php - SQL : How to reduce multiple time querying the same table ..查询优化

sql-server - 为什么使用声明变量作为参数的 UDF 调用比使用硬编码参数调用快得多

tsql - T-SQL 循环查询结果

sql - Oracle:多对多:需要两个外键约束?