我想要一个查询,它会返回所有订单行项目都有库存的订单的Order_ID列表。以下是要说明的表格:
test_Order:
Order_ID
1001
1002
1003
test_OrderLine:
OrderLine_ID|Order_ID|Item_ID|Quantity
10|1001|101|1
11|1001|102|1
12|1001|103|1
13|1002|101|4
14|1002|102|1
15|1003|101|1
16|1003|104|4
test_Item:
Item_ID|InStockQuantity
101|3
102|1
103|7
因此,在上面的示例中,只应返回Order_ID 1001,因为:
这显然不正确,但有点像:
SELECT O.Order_ID
FROM test_Order AS O
LEFT JOIN test_OrderLine OL
ON O.Order_ID = OL.Order_ID
LEFT JOIN test_Item I
ON OL.Item_ID = I.Item_ID
WHERE (OL.Quantity <= I.InStockQuantity)
GROUP BY O.Order_ID
该查询的问题在于,只有一个OrderLines需要有一个Quantity&lt; = InStockQuantity才能使Order_ID出现在结果中,而我只希望它出现在结果中,如果订单中的所有数量都是&lt; = InStockQuantities。
我读了一些关于“ALL”运算符的内容,但看不出它在子查询中是如何工作的。
答案 0 :(得分:0)
考虑此问题的另一种方法是返回没有订单行的order_ids,订单行的数量大于库存数量。使用左连接和coalesce
可以让您完全缺货,就像它们的数量为0一样:
SELECT order_id
FROM test_order
WHERE order_id NOT IN (SELECT order_id
FROM test_orderline o
LEFT JOIN test_item i ON o.item_id = i.item_id
WHERE o.quantity > COALESCE(i.instockquantity, 0))
答案 1 :(得分:0)
使用not exists()
:
select o.Order_id
from test_Order as o
where not exists (
select 1
from test_OrderLine as ol
left join test_Item as i
on ol.Item_id = i.Item_id
where ol.Order_id = o.Order_id
and OL.Quantity > coalesce(I.InStockQuantity,0)
)
rextester演示:http://rextester.com/JGHQ62465
返回:
+----------+
| Order_id |
+----------+
| 1001 |
+----------+
答案 2 :(得分:0)
这是一个小提琴:http://rextester.com/UPC62237
我相信这可以满足您的需求。我评论说你可以理解查询背后的逻辑。
create table test_Order ([Order_id] int);
insert into test_Order ([Order_id]) values
(1001)
,(1002)
,(1003);
create table test_OrderLine ([OrderLine_id] int, [Order_id] int, [Item_id] int, [Quantity] int) ;
insert into test_OrderLine ([OrderLine_id], [Order_id], [Item_id], [Quantity]) values
(10, 1001, 101, 1)
,(11, 1001, 102, 1)
,(12, 1001, 103, 1)
,(13, 1002, 101, 4)
,(14, 1002, 102, 1)
,(15, 1003, 101, 1)
,(16, 1003, 104, 4)
;
create table test_Item ([Item_id] int, [InStockQuantity] int) ;
insert into test_Item ([Item_id], [InStockQuantity]) values
(101, 3)
,(102, 1)
,(103, 7)
;
select original_orderline_count.Order_id
/*first table gets each order with it's line count*/
from (select order_line.Order_id, count(order_line.OrderLine_id) as line_count
from test_OrderLine order_line
group by order_line.Order_id) as original_orderline_count
/*second table gets count of order lines in stock by order*/
inner join (select ol.Order_id, count(ol.OrderLine_id) as line_count
from test_Order o
inner join test_OrderLine ol on o.Order_id = ol.Order_id
inner join test_Item i on i.Item_id = ol.Item_id
where ol.Quantity <= i.InStockQuantity
group by ol.Order_id) as orderline_in_stock
/*join the two tables on order id line count matching*/
on original_orderline_count.Order_id = orderline_in_stock.Order_id
and original_orderline_count.line_count = orderline_in_stock.line_count