我正在查看输出类似以下内容的查询:
Group | Date 1 | Value 1 | Date 2 | Value 2
------+------------+---------+-------------+--------
A | 2011-06-15 | 105 | NULL | NULL
A | NULL | NULL | 2011-06-16 | 107
B | 2011-06-18 | 567 | NULL | NULL
B | NULL | NULL | 2011-06-20 | 525
我想要的是按小组“扁平化”这些结果 - 有点像行COALESCE
:
Group | Date 1 | Value 1 | Date 2 | Value 2
------+------------+---------+-------------+--------
A | 2011-06-15 | 105 | 2011-06-16 | 107
B | 2011-06-18 | 567 | 2011-06-20 | 525
请注意,每组只会有2行;这不是处理任意数量的数据点,它本质上是一个“前后”查询。
是否可以在单次传递中执行此操作? (结果中有大量数据)。这意味着:
MIN
和MAX
,然后加入这些日期以获取值的明显解决方案。如上所述,这是一个昂贵的查询的结果集,我正在努力不加倍负载。我知道我可以在技术上用光标做到这一点,但我真的真的不愿意,除非有人能向我证明它比任何基于集合的选项更快。
P.S。请注意,对于组“B”,值2低于值1.我已明确地说明为什么单个GROUP BY
采用两个日期的MIN
和MAX
和价值不会产生预期的结果。这些值必须与日期相关联。
答案 0 :(得分:0)
假设你总是在Group
中得到对,你可以做GROUP BY [Group]
,对于4列中的每一列,选择MAX()
(基本上取非空值)。
修改:如果您的数据集中包含“Group”,“Date”和“Value”列,并希望合并这些数据集以便您拥有“Group”,“Date 1”, “值1”,“日期2”和“值2”列使用此(第一个CTE代表测试数据):
WITH Results AS (
SELECT 'A' [Group], CONVERT(datetime, '2011-06-15') [Date], 105 [Value]
UNION ALL
SELECT 'A' [Group], CONVERT(datetime, '2011-06-16') [Date], 107 [Value]
UNION ALL
SELECT 'B' [Group], CONVERT(datetime, '2011-06-18') [Date], 567 [Value]
UNION ALL
SELECT 'B' [Group], CONVERT(datetime, '2011-06-20') [Date], 525 [Value]
),
ResultsIndexed AS (
SELECT ROW_NUMBER() OVER (PARTITION BY r.[Group] ORDER BY r.[Date]) ix, r.* FROM Results r
)
SELECT r1.[Group], r1.[Date] [Date 1], r1.[Value] [Value 1], r2.[Date] [Date 1], r2.[Value] [Value 1]
FROM ResultsIndexed r1
JOIN ResultsIndexed r2 ON (r1.[Group] = r2.[Group]) AND (r2.[ix] = 2)
WHERE r1.[ix] = 1
答案 1 :(得分:0)
不确定这是否是你想要的。如果你每组只有两行,你可以试试这个。
;WITH cte as
(
-- You sql output here
SELECT *
FROM table
)
SELECT a1.group,a1.date1,a1.value1,a2.date2,a2.value2
FROM cte a1
INNER JOIN cte a2
ON a2.date2 IS NOT NULL
AND a1.group = a2.group
WHERE a1.date1 IS NOT NULL