我有一张桌子' order'包含摘要订单信息和表' orderItem'与订单的每个项目。
我的问题是:选择列的总和' orderQTY'来自'订单'如果我加入orderItem表,我得到一个不正确的总数。
下面的第一个查询给出了正确的总数。 但是,只要我将连接添加到orderItem,总和结果就会错误地复制' orderqty'每个orderitem记录的列。
nb:我知道下面没有使用联接,也没有必要。 我已经删除了引用联接表的条款以简化 问题
--RETURNS Correct value
select sum(o.orderqty)
from [order] o
--RETURNS the sum containing duplicates of o.orderqty
select sum(o.orderqty)
from [order] o
join OrderItem oi on o.Id = oi.OrderId
- 补充说明:----
我想要总结列' orderqty'来自表' order'加入orderItem时,例如:
每个订单会有多个orderItem,但我只想显示每个订单只计算一次订单表中的orderqty。
select sum(o.ordertotal)
from [order] o with(NOLOCK)
join OrderItem oi on o.Id = oi.OrderId
where oi.mycolumn = 1
或者我需要做类似的事情:
select sum(o.ordertotal)
from [order] o with(NOLOCK)
where o.id in (select orderid from orderitem where x = y)
答案 0 :(得分:4)
它会返回不同的结果,因为join
会将行数或过滤行数相乘,这两行都会影响总和。目前还不清楚你真正想做什么。如果您只想要具有订单行的订单数量的总和,则使用exists:
select sum(o.orderqty)
from [order] o
where exists (select 1
from OrderItem oi
where o.Id = oi.OrderId
);
答案 1 :(得分:1)
您可以使用row_number函数对每个分组(在本例中为order.id)求和一次:
select sum(orderqty)
from (
select
case row_number() over(partition by o.Id order by o.id)
when 1 then orderqty
else 0
end as orderqty
from [order] o
join OrderItem oi on o.Id = oi.OrderId
) o
答案 2 :(得分:0)
加入工作以创建组合来自多个表的数据的结果集。然后,SQL在此组合结果集上运行聚合函数和where子句。所以想象你有2个订单,1个单项,1个2项:
// Order table
OrderId OrderQty
1 5
2 3
// OrderItem table
OrderId ItemId
1 1
2 1
2 2
您的加入会给您以下结果:
OrderId OrderQty OrderId ItemId
1 5 1 1
2 3 2 1
2 3 2 2
所以,当你SUM(OrderQty)
时,我认为你想要的是11而不是8。在这种情况下,链接到另一个表是没有意义的......
答案 3 :(得分:0)
FROM子句(就像它一样)计算中间table。
SELECT子句表达式
sum(o.orderqty)
并不表示"表orderqty
"的o
列的总和。它表示" FROM子句"生成的中间表的o.orderqty
列的总和。
以下是示例表:
// [order]
Id orderqty
1 33
2 66
// OrderItem
OrderId ItemId
2 7
1 8
1 9
这是第二个查询:
select sum(o.orderqty)
from [order] o
join OrderItem oi on o.Id = oi.OrderId
首先,FROM计算一个"交叉产品"它具有您加入的表中的一行的所有可能组合。所以它的每一行都有一个来自每个表的子行。每个子行都有列名,如源表列名,但源表名或别名前缀为点。 (如果没有歧义,您不需要提及前缀和点来引用FROM子句表列。)
// [order] o join OrderItem oi
o.Id o.orderqty oi.OrderId oi.ItemId
1 33 2 7
1 33 1 8
1 33 1 9
2 66 2 7
2 66 1 8
2 66 1 9
然后删除ON和WHERE失败的行:
// [order] o join OrderItem oi on o.Id = oi.OrderId
o.Id o.orderqty oi.OrderId oi.ItemId
1 33 1 8
1 33 1 9
2 66 2 7
这是SELECT使用的第二个查询FROM中间表。这是SELECT使用的第一个查询的FROM中间表:
// [order] o
o.Id o.orderqty
1 33
2 66
因此第二个查询的SUM(o.orderqty)是33 + 33 + 66,而第一个查询是33 + 66。由于对于[order]的FROM子句表需要SUM,因此需要第一个查询。
(我们也可以在逐个连接的基础上对此进行描述,这使我们可以解释LEFT JOIN与INNER JOIN,CROSS JOIN和","以及USING和NATURAL如何制作差。)
重新更新:您尚未从查询中解释想要返回的行。也许你想要:
select oi.Id, oi.orderId, o.orderqty, ...
from [order] o
join OrderItem oi on o.Id = oi.OrderId
或
select ..., (select sum(orderqty) from [order]) as totalqty, ...