我有一个如下表:
+-------------------------+------+------+------+------+
| 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行)。我担心多个按订单查询可能会降低查询的性能。但是,如果没有更清洁的解决方案出现,我会继续努力。
答案 0 :(得分:4)
如果您的订单按[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]
答案 1 :(得分:1)
您可以尝试执行以下操作以避免排序。我知道一开始定义50个变量非常繁琐,但是您以后不必担心。
declare @A int = (select top 1 A from #Table where A is not null)
declare @B int = (select top 1 B from #Table where B is not null)
declare @C int = (select top 1 C from #Table where C is not null)
declare @D int = (select top 1 D from #Table where D is not null)
select top 1 Date,@A,@B,@C,@D
from #Table
答案 2 :(得分:1)
我还没有测试过,但是看起来确实很邪恶:
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.SystemKey == Key.F10)
{
YourLogic(e.SystemKey);
}
switch (e.Key)
{
case Key.F1:
case Key.F2:
}
}
没有窗口功能:
with cte as (
select date
, a, max(case when a is not null then date end) over () as date_a
, b, max(case when b is not null then date end) over () as date_b
, c, max(case when c is not null then date end) over () as date_c
, d, max(case when d is not null then date end) over () as date_d
from t
)
select max(date) as date
, min(case when date = date_a then a end) as a
, min(case when date = date_b then b end) as b
, min(case when date = date_c then c end) as c
, min(case when date = date_d then d end) as d
from cte