新列的 SQL 不同分组依据
Posted
技术标签:
【中文标题】新列的 SQL 不同分组依据【英文标题】:SQL Different Group By For New Column 【发布时间】:2020-09-09 16:34:53 【问题描述】:我已经在阳光下尝试了所有搜索来尝试解决这个问题,或者我没有正确搜索
我有一个带有子查询的查询,里面有 2 个联合查询
例子:-
SELECT name, status , SUM(TestCount) as ‘TestCount’
FROM(
select e1.reference as reference,
e1.name as name,
e1.status as status,
, SUM(CASE WHEN e1.date IS NOT NULL THEN 1 ELSE 0 END) as TestCount
FROM dbo.table1 as e1
WHERE e1.status IN('A','B','C')
GROUP BY e1.name, e1.status
UNION ALL
select e2.reference as reference,
e2.name as name,
e2.status as status,
SUM(CASE WHEN e2.date IS NOT NULL THEN 1 ELSE 0 END) as TestCount
FROM dbo.table2 as e2
WHERE e2.status IN('A','B','C')
GROUP BY e2.name, e2.status
) t
GROUP BY Name, Status
我想在我的子查询中添加一个 SUM CASE WHEN 列,然后在顶部将其拉出,仅按名称分组,而不是状态。 (因此,如果一个人的名字出现 5 次以获得 5 种不同的状态',则只需为他们的名字显示相同的数字 5 次)。问题是,如果我使用 WHERE 子句(内部)或 HAVING 外部,它会过滤掉具有最后一列的 SUM CASE WHEN 条件的状态
例如
状态:-
一个 乙 C D E - 这里是总和案例的来源
我想使用 WHERE 仅显示 A 、 B 、 C 、 D ,但我想计算 E..
希望这是有道理的
根据建议编辑:-
SUM(CASE WHEN MONTH(Field1Date) = MONTH(GETDATE()) AND YEAR(Field1Date) = YEAR(GETDATE()) AND TypeCode IN('A', 'B', 'C') THEN 1
ELSE 0 END) OVER (PARTITION BY Name) as full_count
这会导致:-
Msg 8120, Level 16, State 1, Line 1
Column 't.Field1Date' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 1
Column 't.Field1Date' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 1
Column 't.TypeCode' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 1
Column 't.TypeCode' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 1
Column 't.TypeCode' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
这样做然后将错误减少到2:-
SUM(CASE WHEN MONTH(Field1Date) = MONTH(GETDATE()) AND YEAR(Field1Date) = YEAR(GETDATE()) AND TypeCode IN('A', 'B', 'C') THEN 1
ELSE 0 END) OVER (PARTITION BY Name, Field1Date, TypeCode) as full_count
Msg 8120, Level 16, State 1, Line 2
Column 't.Field1Date' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 2
Column 't.TypeCode' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
我可以通过将最后 2 个错误添加到 GROUP BY 来消除它们,但如果这有意义的话,我不想一开始就对它们进行 GROUP BY?
如果我将它们添加到 GROUP BY 以克服错误,则 SUM 始终为 0,因为内部查询中的 WHERE 语句会过滤掉计数所在的所有“状态”
对不起,我应该说这是 SQL Server。 SSMS 中的 TSQL
【问题讨论】:
SELECT name, status , SUM(TestCount)
@jarlh 但它不会显示,因为使用 WHERES 过滤掉了 TestCount,因为并非所有状态都需要显示
您使用的是什么 DBMS?请始终使用您想要回答的 DBMS 标记 SQL 问题。在您的 TestCount 别名周围有一些反引号,其中标准 SQL 需要双引号。这可能表示 mysql。然后,您可以从 SQL Server 的典型 dbo 架构中进行选择。不同的 DBMS 具有不同的功能,因此了解您使用的是哪一个对我们来说很重要。我在回答中使用了标准 SQL 查询。希望这对你有用。
【参考方案1】:
您可能正在寻找SUM OVER
来获得一个组的总数。您没有告诉我们您使用的是哪个 DBMS,但这是许多 DBMS 中可用的标准 SQL 函数。
我已将您的 SUM(CASE WHEN date IS NOT NULL THEN 1 ELSE 0 END)
简化为 COUNT(date)
。我还从内部查询中删除了聚合,因为无论如何您都必须在主查询中进行聚合。
SELECT
name,
status,
COUNT(date) as partial_count,
SUM(COUNT(date)) OVER (PARTITION BY name) as full_count
FROM
(
SELECT name, status, date FROM dbo.table1 WHERE status IN ('A', 'B', 'C')
UNION ALL
SELECT name, status, date FROM dbo.table2 WHERE status IN ('A', 'B', 'C')
) t
GROUP BY name, status
ORDER BY name, status;
【讨论】:
这太好了,到目前为止非常感谢。我的查询比我想象的要复杂得多,但为了问题的重点,我已经匿名了。我现在已经将我所有的 SUM(CASE WHEN's) 从内部查询移到了外部查询,这更有意义。问题是,我的 SUM OVER 实际上是 SUM(CASE WHEN field1 IS NOT NULL and field2 IN ('a' , 'b' , 'c') THEN 1 ELSE 0 END) OVER (PARTITION BY name) as full_count。然后我得到它抱怨 GROUP BY,所以我将它添加到 PARTITION BY 列表中。但它不会在不属于 GROUP BY 的情况下执行 在主帖中添加了更多关于我尝试过的 @Thorsten Kettner 的 cmets 我猜你只是缺少SUM
。解析函数SUM OVER
出现在聚合SUM(CASE ...)
之后,因此您将拥有两个SUM
:SUM(SUM(CASE WHEN field1 IS NOT NULL and field2 IN ('a' , 'b' , 'c') THEN 1 ELSE 0 END)) OVER (PARTITION BY name)
。
现在可以工作了 Thorsten - 谢谢。它仍然显示 0 计数,大概是因为使用 WHERE。因为计数落入例如状态“D”的结果中。我一取出 WHERE,它就会在 Status D 旁边显示一个计数
计数为 0 意味着虽然存在状态 A、B 和/或 C 的行,但它们的所有日期均为空。以上是关于新列的 SQL 不同分组依据的主要内容,如果未能解决你的问题,请参考以下文章