我在sql server上有一组数据,如:
ID ID_Invoice Article Quantity Status
1 10 carrot 10 null
2 10 carrot 5 C
3 10 onion 8 null
4 10 onion 4 C
5 11 tomato 20 null
6 11 tomato 18 C
7 11 onion 2 null
8 11 onion 1 C
这意味着客户订购了10个胡萝卜和8个洋葱(在一张发票上)但实际上只收到了5个胡萝卜和4个洋葱。如果status为null则为原始数量,如果status为C则为校正数量
我需要生成一个像
这样的表格ID ID_Invoice Article Quantity
1 10 carrot -5
2 10 onion -4
3 11 tomato -2
4 11 onion -1
显示每张发票上的订购数量和实际数量之间的差异。我不知道如何开始。任何帮助深深赞赏:)
答案 0 :(得分:8)
带有简单CASE表达式的选项,没有过多的JOIN
SELECT ID_Invoice, Article,
SUM(CASE WHEN Status IS NULL
THEN -1 * Quantity ELSE Quantity END) AS Quantity
FROM dbo.test38
GROUP BY ID_Invoice, Article
结果:
ID_Invoice Article Quantity
10 carrot -5
10 onion -4
11 onion -1
11 tomato -2
SQLFiddle上的演示
答案 1 :(得分:2)
您没有指定,您正在使用哪个RDBMS,但我的答案是符合ANSI-SQL标准:)与每个有效的RDBMS一起使用。
SELECT
yt1.ID_Invoice,
yt1.Article,
yt2.Quantity - yt1.Quantity AS Quantity
FROM
yourTable yt1
INNER JOIN yourTable yt2 ON yt1.ID_Invoice = yt2.ID_Invoice
AND yt1.Article = yt2.Article
AND yt2.Status = 'C'
WHERE
yt1.Status IS NULL
这个答案是假设的,总是一个状态为NULL的记录和状态为“C”的相应行。如果不是这种情况,你必须像这样调整它:
SELECT
yt1.ID_Invoice,
yt1.Article,
CASE WHEN yt2.Quantity IS NULL THEN yt1.Quantity ELSE yt2.Quantity - yt1.Quantity END AS Quantity
FROM
yourTable yt1
LEFT JOIN yourTable yt2 ON yt1.ID_Invoice = yt2.ID_Invoice
AND yt1.Article = yt2.Article
AND yt2.Status = 'C'
WHERE
yt1.Status IS NULL
答案 2 :(得分:2)
资源密集程度最低:
SELECT id_invoice
, article
, org_quantity
, new_quantity
, new_quantity - org_quantity diff
FROM (SELECT id_invoice
, article
, max(CASE WHEN status IS NULL THEN quantity else null END) org_quantity
, max(CASE WHEN status = 'C' THEN quantity else null END) new_quantity
FROM orders
GROUP BY id_invoice
, article)
答案 3 :(得分:1)
首先,您必须通过进行2次查询将实际与订购分开,然后您必须将订单连接到实际的..这样的事情
select
Recived.ID,
Recived.ID_Invoice,
Recived.Article,
Recived.Quantity - Ordered.Quantity as Quantity
from
(select * from dataTable where Status is null) as Ordered
left join (select * from dataTable where Status = 'C') as Recived on (Ordered.ID_Invoice = Recived.ID_Invoice and Ordered.Article = Recived.Article )
请注意!如果您在“左连接”中使用每个文章的ID而不是比较varchars,那么您会更好。
这是一个小提琴示例: http://sqlfiddle.com/#!2/16666/1