我们有一个销售报告,从多个表中提取数据,我的查询显示正确的数据,但具有多个订单项的订单除外,即每个订单项行上都列出了订单总计。
如何在具有最小订单项ID(对于该订单)但仍列出每个订单项行的行上仅列出订单总计一次?谢谢!
数据结构:
订单表:
订单项表:
结果应该是:
Order_ID Total Line_Item_Price Line_item_Qty Line_Item_ID
---------- ------- ----------------- --------------- --------------
10001 200 100 2 32001
10002 150 150 1 32002
10003 210 55 1 32003
10003 30 2 32004
10003 95 1 32005
10004 125 125 1 32006
答案 0 :(得分:1)
这应该在不在SQL中的应用程序中完成。
但是你可以使用window functions 来做到这一点
select o.order_id,
case row_number() over (partition by o.order_id order by line_item_id)
when 1 then o.total
end as total,
li.line_item_price,
li.line_item_qty,
li.line_item_id
from orders o
join line_item li on o.order_id = li.order_id
order by o.order_id, li.line_item_id;
row_number()
为每个订单的每个订单项分配一个唯一的行号。当数字为1
时,显示总数,否则不显示。
在关系数据库中除非您指定order by
,否则不存在“第一行” - 在这种情况下,“第一行”是具有最小line_item_id
的订单项
在线示例:http://rextester.com/TQOIX50171
不相关,但是:将总数存储在orders
表中并不是一个非常好的主意。在标准化设计中,您不应存储可从现有数据轻松派生的信息。
答案 1 :(得分:0)
这样做是通过他们的物品获得订单并对其进行排名。因此,最小的item_id是该订单的等级1,最新的是最后的等级。
ROW_NUMBER()是给出查询输出中行的索引的函数(第1行= 1,第2行= 2)。然后我们可以将它与OVER(PARTITION BY)结合起来,这意味着获取某个窗口内的行号,一个分区。在这种情况下,我们想要为Order_IDs的窗口编号行。我们一起使用ORDER BY来说明我们如何在窗口中对行进行排序
当我们有这个表时,我们可以在其上写一个查询,只显示item_rank = 1
的行的总数WITH rank_items_for_orders AS (
SELECT
Order_ID,
Line_Item_Price,
Line_Item_Qty,
Line_Item_ID,
Total,
ROW_NUMBER()
OVER (PARTITION BY Order_ID, ORDER BY Line_Item_ID ASC)
AS order_the_items_IDs
FROM orders o
LEFT JOIN line_items li ON o.order_id = li.order_id
ORDER BY Order_ID ASC)
SELECT
Order_ID,
Line_Item_Price,
Line_Item_Qty,
Line_Item_ID,
CASE WHEN order_the_items_IDs = 1
THEN Total ELSE NULL END
AS Total
FROM
rank_items_for_orders