在 SQL 中使用 Group By 和 Aggregate - 获取错误“选择列表中的列无效,因为它不包含在聚合函数或 GROUP BY 中”
Posted
技术标签:
【中文标题】在 SQL 中使用 Group By 和 Aggregate - 获取错误“选择列表中的列无效,因为它不包含在聚合函数或 GROUP BY 中”【英文标题】:Using Group By and Aggregate in SQL - Getting the error 'Column invalid in select list because it is not contained in aggregate funct or GROUP BY' 【发布时间】:2020-04-17 10:22:37 【问题描述】:我正在连接 2 个表中的数据,以获取数据库中客户的最后交易日期。这是我正在尝试做的一个简化示例:
SELECT c.CustomerID
c.CustomerFirstName
c.CustomerLastName
MAX(t.TransactionDate)
FROM [db].[customertable] C
LEFT JOIN [TransactionTable] T on c.CustomerID = t.CustomerID
GROUP BY c.CustomerID
按 t.TransactionDate 排序
但是在执行此代码时,我收到以下错误消息:
'选择列表中的列无效,因为它不包含在聚合函数或 GROUP BY 子句中'
我花了一些时间尝试解决这个问题,发现将 MAX() 放在客户的名字和姓氏前面是有效的,消除了错误消息,输出似乎是我想要的。
虽然我想知道这是否是不好的做法?我按 CustomerID 分组,这是一个唯一的参考 - 每个 CustomerID 只有一个名字和一个姓氏,因此我是否正确地说将最大值放在名字/姓氏前面不会有任何除了使我的查询正常工作之外的影响?
我在网上找到的其他解决方案建议子查询,但我仍在学习 SQL,所以不知道该怎么做。
谢谢
【问题讨论】:
这里的错误非常明显;您在此处不了解错误的哪一部分,以便我们尝试详细说明。 T-SQL 要求所有非聚合列都用 agg 函数括起来:***.com/questions/33629168/… 相关:T-SQL 不支持T301 aka Functional dependencies 在分组中使用 c.CustomerFirstName, c.CustomerLastName 【参考方案1】:只包括所有非聚合列:
SELECT c.CustomerID, c.CustomerFirstName, c.CustomerLastName,
MAX(t.TransactionDate)
FROM [db].[customertable] C LEFT JOIN
[TransactionTable] T
ON c.CustomerID = t.CustomerID
GROUP BY c.CustomerID, c.CustomerFirstName, c.CustomerLastName;
通常,这种类型的查询使用相关子查询或横向连接(即apply
)会更快:
select c.*, -- or whatever columns you want
t.max_TransactionDate
from [db].[customertable] C outer apply
(select max(t.TransactionDate) as max_TransactionDate
from [TransactionTable] t
where c.CustomerID = t.CustomerID
) t;
特别是在TransactionTable(CustomerID, TransactionDate desc)
上的索引,这应该比group by
的版本快得多。
【讨论】:
以上是关于在 SQL 中使用 Group By 和 Aggregate - 获取错误“选择列表中的列无效,因为它不包含在聚合函数或 GROUP BY 中”的主要内容,如果未能解决你的问题,请参考以下文章
在 SQL 中使用 Group By 和 Aggregate - 获取错误“选择列表中的列无效,因为它不包含在聚合函数或 GROUP BY 中”
在 sql 查询中使用 group/order by 和 union 子句