首页 > 解决方案 > 在 group by 中,有没有办法告诉 SQL 特定列不需要聚合函数?

问题描述

我最近开始使用 T-SQL,并且在按功能分组时遇到了困难。

假设我有一个包含 3 列的表:Column_1、Column_2 和 Column_3。我知道对于 Column_1 的给定值,Column_2 将始终具有给定值。另一方面,Column_3 独立于 Column_1。

所以表格可能如下所示:

Column_1    Column_2    Column_3 
1           42          57 
1           42          35 
2           3           5
2           3           6 
5           78          45 

我想对 Column_1 进行分组以聚合 Column_3(假设使用 sum())。但是,当我进行分组时,即使我知道没有必要,我也必须分组或聚合 Column_2。

所以我的 SQL 请求是:

select Column_1, Column_2, sum(Column_3) 
from Table 
group by Column_1, Column_2

或者

select Column_1, max(Column_2), sum(Column_3) 
from Table 
group by Column_1
(using max as a workaround to avoid grouping by Column_2)

我的问题是:有没有办法告诉 SQL Column_2 不需要聚合函数并让 SQL 检查假设是否正确?

我认为这是一个最佳选择,因为它使我能够确定我的假设是正确的。在使用前两个请求时,我永远不能 100% 确定是这种情况(除非我在请求之前以另一种方式检查它)并且可能会导致难以识别的错误(尤其是在使用最大解决方法时)。

理想情况下,我希望能够编写如下内容:

select Column_1, no_agg_necessary(Column_2), sum(Column_3) 
from Table 
group by Column_1

如果 Column_2 值在按给定 Column_1 值分组时不相同,则会出现警告。

我在想这样的选择 Column_2 可以满足我的需求:

case when count(distinct Column_2) = 1 then max(Column_2) else raiseerror() end as Column_2

但是在这种情况下似乎不可能使用 raiseerror() 并且添加 distinct 会减慢请求。

你知道任何可以满足我需求的 SQL 功能吗?

标签: sqltsqlgroup-byaggregate-functions

解决方案


在 SQL Server 或任何其他数据库中不支持您要求的内容。某些数据库支持功能依赖,但它们会查看表的定义以查看值是否必须相关(即column1is unique)。他们不检查数据在其他情况下是否具有唯一值。

一般来说,SQL——尤其是 SQL Server——并不特别擅长在SELECT语句中生成错误。可以使用CASE表达式。在非聚合查询中,SQL Server 保证评估顺序,甚至在编译阶段不评估错误。

所以,你可以写你想要的:

select x,
       (case when min(y) = max(y)
             then min(y) else convert(int, 'Bad column value')
        end)
from (values (1, 1), (1, 1), (1, 2)) v(x, y)
group by x;

我真的不建议以这种方式处理查询。您应该将数据验证作为一个单独的步骤,这样您就不会对获得的结果感到惊讶。


推荐阅读