MSSQL 通过 "updating" 这些值对具有不同值的行进行分组
MSSQL group rows with different values by "updating" those values
假设以下数据:
需要对这些数据进行分组才能得到这个结果:
如您所见,id
只是与 STRING_AGG(id, ' ') WITHIN GROUP (ORDER BY id ASC)
聚合。 accountNums
有点棘手。只有当 refNum
有 2 个 accountNum
s 10040
和 10041
时,才应该用值 2
替换它们。如果任何 refNum
只有其中之一 accountNums
,则不应替换它们。任何其他 accountNum
.
也是如此
我尝试了以下 SQL 查询,但无法正确分组:
SELECT STRING_AGG(f.id, ' ') WITHIN GROUP (
ORDER BY f.id ASC),
f.refNum,
CASE
WHEN EXISTS ( SELECT 1
FROM Foo f2
WHERE (f2.accountNum = 10040
OR f2.accountNum = 10041)
AND f2.id != f.id)
AND (f.accountNum = 10040
OR f.accountNum = 10041)
THEN 2
ELSE f.accountNum
END AS accountNumUpdated,
SUM(f.value) AS val
FROM Foo f
GROUP BY f.refNum,
accountNumUpdated
此查询的问题是 accountNumUpdated
在 GROUP BY
子句中未知。此外,我无法将 CASE WHEN
移动到 GROUP BY
,因为那里也不允许使用子查询。
由于我找不到解决这些问题的方法,问题是,我需要如何更改查询才能获得我想要的结果?
确切的 SQL 服务器版本是:
Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64)
Aug 22 2017 17:04:49
Copyright (C) 2017 Microsoft Corporation
Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)
有什么不明白的,尽管问
尝试对您的结果使用 cte
。由于您已经计算出您的价值
; WITH CTE AS (
SELECT f.id,
f.refNum,
CASE
WHEN EXISTS ( SELECT 1
FROM Foo f2
WHERE (f2.accountNum = 10040
OR f2.accountNum = 10041)
AND f2.id != f1.id
AND f2.refNum = f1.refNum) --- add this since you want to combine for one refno
AND (f.accountNum = 10040
OR f.accountNum = 10041)
THEN 2
ELSE f.accountNum
END) AS accountNumUpdated,
f.value AS val
FROM Foo f group by f.id, f.refnum, f.value
)
SELECT STRING_AGG(id, ' ') WITHIN GROUP ( ORDER BY id ASC) ,
max(refNum) as refNum, max(accountNumUpdated) as accountNumUpdated , sum(val) as val
FROM CTE GROUP BY accountNumUpdated
假设以下数据:
需要对这些数据进行分组才能得到这个结果:
如您所见,id
只是与 STRING_AGG(id, ' ') WITHIN GROUP (ORDER BY id ASC)
聚合。 accountNums
有点棘手。只有当 refNum
有 2 个 accountNum
s 10040
和 10041
时,才应该用值 2
替换它们。如果任何 refNum
只有其中之一 accountNums
,则不应替换它们。任何其他 accountNum
.
我尝试了以下 SQL 查询,但无法正确分组:
SELECT STRING_AGG(f.id, ' ') WITHIN GROUP (
ORDER BY f.id ASC),
f.refNum,
CASE
WHEN EXISTS ( SELECT 1
FROM Foo f2
WHERE (f2.accountNum = 10040
OR f2.accountNum = 10041)
AND f2.id != f.id)
AND (f.accountNum = 10040
OR f.accountNum = 10041)
THEN 2
ELSE f.accountNum
END AS accountNumUpdated,
SUM(f.value) AS val
FROM Foo f
GROUP BY f.refNum,
accountNumUpdated
此查询的问题是 accountNumUpdated
在 GROUP BY
子句中未知。此外,我无法将 CASE WHEN
移动到 GROUP BY
,因为那里也不允许使用子查询。
由于我找不到解决这些问题的方法,问题是,我需要如何更改查询才能获得我想要的结果?
确切的 SQL 服务器版本是:
Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64)
Aug 22 2017 17:04:49
Copyright (C) 2017 Microsoft Corporation
Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)
有什么不明白的,尽管问
尝试对您的结果使用 cte
。由于您已经计算出您的价值
; WITH CTE AS (
SELECT f.id,
f.refNum,
CASE
WHEN EXISTS ( SELECT 1
FROM Foo f2
WHERE (f2.accountNum = 10040
OR f2.accountNum = 10041)
AND f2.id != f1.id
AND f2.refNum = f1.refNum) --- add this since you want to combine for one refno
AND (f.accountNum = 10040
OR f.accountNum = 10041)
THEN 2
ELSE f.accountNum
END) AS accountNumUpdated,
f.value AS val
FROM Foo f group by f.id, f.refnum, f.value
)
SELECT STRING_AGG(id, ' ') WITHIN GROUP ( ORDER BY id ASC) ,
max(refNum) as refNum, max(accountNumUpdated) as accountNumUpdated , sum(val) as val
FROM CTE GROUP BY accountNumUpdated