我想在一行中查找聚合在多个列的属性上的数据。这听起来像是一堆乱码,所以我给你举个例子......这是一个有三列的数据库表:
GroupingId Type Date
1 NULL 1/1/11
1 NULL 2/2/22
2 NULL 1/1/11
2 A 2/2/22
3 A 1/1/11
3 B 2/2/22
4 A 1/1/11
4 NULL 2/2/22
我想做一个SELECT,和GROUP BY GroupingId。这很容易。
但是对于其他两列,我想要一些真正依赖于两列的东西。如果我只想要任何给定组的MAX日期,那就很简单了。我真正想要的是Type更喜欢NOT NULL,而Date应该是MAX ...但我希望它们始终来自同一行(Type值为NOT NULL优先)。
所以我的结果应该是
1 NULL 2/2/22 // both Types are null, so last date chosen
2 A 2/2/22 // one Type not null, so that date chosen
3 B 2/2/22 // both Types not null, so last date chosen
4 A 1/1/11 // one Type not null, so that date chosen (and it is not the most recent date)
如果我在日期做MAX,那是不对的。如果我在Type上执行COALESCE,我将在NULL上获得非空值...但不一定是最近的值。
有干净的方法吗?我想我看到如何通过一系列选择,一个表变量和一个UNION来实现这一点,这就是我将要尝试向前发展的方式,但如果有一个干净的SQL解决方案,有人甚至可以在,那将是受欢迎的。
我在SQL Server中,但我猜测如果有一种干净的SQL方法,那么它可能与数据库无关。
答案 0 :(得分:2)
喜欢这样吗?
;WITH CTESample (GroupingId, Type, Date) AS
(
SELECT 1, NULL, '1/1/11' UNION ALL
SELECT 1, NULL, '2/2/22' UNION ALL
SELECT 2, NULL, '1/1/11' UNION ALL
SELECT 2, 'A', '2/2/22' UNION ALL
SELECT 3, 'A', '1/1/11' UNION ALL
SELECT 3, 'B', '2/2/22' UNION ALL
SELECT 4, 'A', '1/1/11' UNION ALL
SELECT 4, NULL, '2/2/22'
)
,Partitioned AS
(
SELECT *
,rNum = ROW_NUMBER() OVER (PARTITION BY GroupingID ORDER BY Type DESC, Date DESC)
FROM CTESample
)
SELECT *
FROM Partitioned
WHERE rNum = 1
答案 1 :(得分:1)
这是使用Rank()
的候选人。
所以,我太慢了......不要告诉我的老板。
无论如何一个例子:
SELECT
[sub].[GroupingID],
[sub].[Type],
[sub].[Date]
FROM
(
SELECT
[GroupingID],
[Type],
[Date],
Rank() OVER(PARTITION BY [GroupingID] ORDER BY (CASE WHEN [Type] IS NULL THEN 0 ELSE 1 END) DESC, [Date] DESC, [Type] ASC) AS [Rank]
FROM [Data]
) AS [sub]
WHERE [sub].[Rank] = 1
ORDER BY [GroupingID] ASC