我有一个orders
表,其中包含许多与问题无关的order
特定信息。但是,我然后有了一个orderDetails
foreign key
的{{1}}表。在此(orders.id == orderDetails.orderId)
中,客户可以选择订购多种口味的产品,每种口味在此表中都有一个新条目,该条目链接回到主orderDetails
。
我想做的是选择所有order
中存在所有风味的orders
。因此,如果一个order
有苹果,桃子和橙子,而我查询了苹果和桃子,则它不会返回该顺序,因为我的查询中没有橙色。
我尝试过order
等,但是我觉得解决该问题的唯一方法是循环每个订单并查看详细信息,但这效率极低。有什么想法吗?
subqueries
因此,如果我没有任何桃子存货,我想看看SELECT *
FROM orders
WHERE id IN (SELECT orderId
FROM orderdetails
WHERE flavor IN('apple', 'peach', 'orange'))
AND isInvoiced = 1
AND isShipped = 0
AND isOnHold = 0
中不包含任何桃子:
orders
这里现有查询的问题是它返回所有内容,因为它只是说,肯定,您要苹果……请您要橙色,并且此SELECT *
FROM orders
WHERE id IN (SELECT orderId
FROM orderdetails
WHERE flavor IN ('apple', 'orange'))
AND isInvoiced = 1
AND isShipped = 0
AND isOnHold = 0
包含那些,所以我将其返回。我需要它全部还是全部。
在真实的数据库中,口味是ID的,在此示例中,我只是对其进行了简化。
已请求数据库表...我将继续列出它们,因为它们确实存在。
order
再进行一次编辑,这是我最初的失败尝试:
orders
-------
id
isInvoiced
isShipped
isOnHold
orderDetails
------------
id
orderId
flavorId
ID的列表将根据库存中实际有什么口味而改变。
答案 0 :(得分:0)
基本上,您只能在条件GROUP BY flavor
的情况下HAVING COUNT(*) = 3
。因此,将列出具有这三种风味的订单
select *
from orders o
where exists
(
select x.flavor
from orderdetails x
where x.orderId = o.id
and x.flavor in ('apple', 'peach', 'orange')
group by x.flavor
having count(*) = 3
)
and isInvoiced = 1
and isShipped = 0
and isOnHold = 0
答案 1 :(得分:0)
您可以使用计数功能来确保代表所有风味。
select o.*
from orders o
inner join
(
select orderId, count(*) as flavorCount
from orderdetails
where flavor in ('apple', 'peach', 'orange')
group by orderId
) as t1
on o.orderId = t1.orderId
and isInvoiced = 1
and isShipped = 0
and isOnHold = 0
and t1.falvourCount = 3;
答案 2 :(得分:0)
通过评论“ 我完全意识到,我遗漏了一个非常重要的部分,因为每个订单可能有一种或多种口味,而不必全部呈现。” << / p>
以下查询符合原始要求:“ 我想做的是选择所有包含所有口味的订单”和“ 我需要它全部还是全部。“
一个订单中可能有多个项目涉及一种风味(例如,“苹果派”和“苹果蛋糕”),所以我建议您在Have子句中使用3个case表达式来防止这种情况,同时仍要实现您的目标:
select o.*
from orders as o
inner join (
select orderId
from orderdetails
group by orderId
having sum(case when flavor = 'apple' then 1 else 0 end) > 0
and sum(case when flavor = 'peach' then 1 else 0 end) > 0
and sum(case when flavor = 'orange' then 1 else 0 end) > 0
) as od on o.id = od.orderid
where o.isInvoiced = 1
and o.isShipped = 0
and o.isOnHold = 0
请注意,inner join
的使用将列出的订单限制为仅涉及所有3种口味的订单。
此查询在此处得到证明:http://rextester.com/AKMM54555
答案 3 :(得分:0)
如果您有缺货和有货的口味列表,那会更简单。 因此,例如,如果'peach'缺货,并且'apple'和'orange'缺货,则以下查询将生成仅具有'apple'或'orange'的订单:
SELECT * FROM orders
WHERE
id IN (SELECT id FROM orderdetails WHERE flavor IN ('apple','orange') ) -- in stock
AND
id NOT IN (SELECT id FROM orderdetails WHERE flavor IN ('peach') ) --out of stock
您怎么看?