我使用的是SQL Server 2014。我熟悉在使用GROUP BY
时解决这个特定错误,但在这种情况下,我没有使用GROUP BY
,我不确定解决这个问题的正确方法是什么。我可以用MAX()
包装select中的所有内容,但这并不理想,尤其是因为我的实际查询比下面显示的简化查询有更多的select(注意,简化查询仍然会复制错误(。
SELECT TOP 100
items.item_pk,
SUM(options.price * options.quantity) AS opt_price,
FROM
dbo.items
LEFT JOIN
options ON qitem_fk = qitem_pk;
我得到这个错误:
列"items.item_pk"在选择列表中无效,因为它既不包含在聚合函数中,也不包含在GROUP BY子句中
如何解决此问题?
您可以尝试使用SUM((OVER(PARTITION BY ORDER BY(语法。这种语法被认为是一种分析函数,但它会产生聚合计算。这允许您在结果集之外生成所需的值,但计算当然是基于结果集中返回的数据。它允许您将聚合计算应用于没有任何聚合函数的查询。
SELECT
items.item_pk,
SUM(options.price * options.quantity) OVER (PARTITION BY items.item_pk ORDER BY items.item_pk) AS opt_price,
FROM dbo.items
LEFT JOIN
options ON qitem_fk = qitem_pk
这里有一个链接可以很好地解释分析函数和聚合函数。链接指向Oracle,但它与任何数据库基本相同。
如果在某些列上使用聚合SUM,则不具有聚合功能的列需要包含在groupby子句中
因此,您需要在查询中添加GROUP BY:
SELECT TOP 100
items.item_pk,
SUM(options.price * options.quantity) AS opt_price,
FROM
dbo.items
LEFT JOIN
options ON qitem_fk = qitem_pk
GROUP BY items.item_pk;
我发现对子查询执行联接可以提供所需的行为。这是因为我现在加入了一个已经执行聚合的表。这可能会对性能造成很大影响,但在我的特殊情况下,这是可以接受的。
SELECT
items.*,
option_aggregate.opt_price
FROM
dbo.items
LEFT JOIN (
SELECT
SUM(
options.price * options.quantity
) AS opt_price,
item_fk
FROM
options
GROUP BY
item_fk
) AS option_aggregate ON option_aggregate.item_fk = items.item_pk