为什么必须对 CASE 语句中的列进行 GROUP BY?
我正在尝试在 SQL Server 2008 中对一个表运行查询,其中某些数据输入不一致,我必须处理这个问题。
表数据示例:
OrderID Qty Price MarkedUpTotal
1 10 1.00 11.00
1 -1 1.00 -1.10
1 -1 1.00 1.10
我必须处理数量为负但 MarkedUpTotal 输入为正的情况。
我想运行以下查询:
SELECT OrderID, SUM(Qty) as OrderTotalQty,
SUM(Qty*Price) as InternalCost,
CASE WHEN Qty < 0 and MarkedUpTotal > 0
THEN sum(-1*MarkedUpTotal)
ELSE SUM(MarkedUpTotal) END as ClientCost
FROM OrderItems
GROUP BY OrderID
但是,运行此查询时出现以下错误:
列数量在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。
列 MarkedUpTotal 在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。
我想要以下结果:
OrderID OrderTotalQty InternalCost ClientCost
1 8 8.00 8.80
对我来说,我必须 GROUP 似乎很奇怪BY Qty 和 MarkedUpTotal 当它们仅由 CASE 语句有条件地使用时。 如果我删除最后一个选择(CASE 语句),查询将正常执行,并且不需要数量或价格位于 GROUP BY 中。
为什么 SQL 需要这个? 是否有一个查询可以完成上述任务?
目前我正在通过使用临时表来解决该问题。 如果需要,我会修改每个条目的 MarkedUpTotal,然后在临时表的主查询中执行简单的 SUM(MarkedUpTotal)。
I'm trying to run a query in SQL Server 2008 against a table where some of the data was entered inconsistently and I have to handle this.
Table data example:
OrderID Qty Price MarkedUpTotal
1 10 1.00 11.00
1 -1 1.00 -1.10
1 -1 1.00 1.10
I have to handle the situation where the Qty is negative but the MarkedUpTotal was entered as positive.
I'd like to run the following query:
SELECT OrderID, SUM(Qty) as OrderTotalQty,
SUM(Qty*Price) as InternalCost,
CASE WHEN Qty < 0 and MarkedUpTotal > 0
THEN sum(-1*MarkedUpTotal)
ELSE SUM(MarkedUpTotal) END as ClientCost
FROM OrderItems
GROUP BY OrderID
However, I get the following error when I run this query:
Column Qty is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Column MarkedUpTotal is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I desire the following result:
OrderID OrderTotalQty InternalCost ClientCost
1 8 8.00 8.80
It seems odd to me that I must GROUP BY Qty and MarkedUpTotal when they are only being used conditionally by the CASE statement. If I remove the last selection (the CASE statement) the query executes fine and does not require Qty or Price to be in the GROUP BY.
Why does SQL require this? Is there a single query that could accomplish the above?
Currently I'm resolving the issue by using a temp table. I modify each entry's MarkedUpTotal if needed and then do a simple SUM(MarkedUpTotal) in the main query from the temp table.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
它给出错误的原因是,您在 CASE 内部对其进行求和 - 这将在外部返回 1 个值。 对于使用 GROUP BY 的 SELECT,看起来就像您将一个数值(可以是常量或来自其他源)作为列传递。
考虑一下您的 SQL 语句,类似于此
现在返回一个新列 (ClientCost),该列未使用任何聚合。
因此,它要求您在 GROUP BY 表达式中使用它。
The reason it gives error is because, you are SUMming it up inside the CASE - which will return 1 value outside. To the SELECT with GROUP BY, it will look like you are passing in a numeric value (which could be a constant or comes from some other source) as a column.
Think of your SQL Statement, similar to this
Now this is returning a new column (ClientCost), which is not using any aggregation.
So, it asks you to use that in GROUP BY expression.
请记住,GROUP BY 语句的结果,或者其中一个或多个列使用聚合函数的语句的结果,每一行都包含其他行的摘要。
您使用的 CASE 表达式取决于各个行的值而不是摘要; 您只能在聚合函数或 WHERE 子句中引用非聚合值(即单行值),因此解决方案将涉及将 CASE 放入聚合函数中,在本例中为 SUM。
Bear in mind that the result of a GROUP BY statement, or of a statement where one or columns uses an aggregate function, has each row containing a summary of other rows.
The CASE expression you're using is dependent on values of individual rows rather than summaries; you may only reference non-aggregate values (i.e. single-row values) in an aggregate function, or in the WHERE clause, so the solution would involve placing your CASE inside an aggregate function, in this case your SUM.
错误是关于这部分的。 Sql Server 应使用什么数量行值?
您可以将其重写为:
或者:
取决于您的意思:)
The error is about this part. What Qty row value should Sql Server use?
You could rewrite it like:
Or:
Depending on what you mean :)
像这样做:
Do it like this:
我突出显示了以下错误:
SQL Server 不知道如何评估 CASE WHEN Qty
0 且 MarkedUpTotal > 0 。 表中的这些记录有 3 个不同的值,这通常不是问题 - 但由于您正在对记录进行分组,因此该表达式毫无意义,因为 SQL Server 不知道在计算时使用这三个值中的哪一个case 表达式,因此它会抛出 OP 中看到的用户不友好的解析错误。
该线程中的所有代码建议都提供了解决方案。
I've highlighted the error below:
SQL server doesn't know how to evaluate
CASE WHEN Qty < 0 and MarkedUpTotal > 0
. You have 3 different values for these records in your table, which is normally not a problem -- but since you're grouping your records, the expression is meaningless since SQL server doesn't know which of the three values to use when it evaluates the case expression, so it throws the user-unfriendly parse errors seen in the OP.All of the code suggestions in this thread provide a solution.