我有以下数据库结构(为清晰起见删除了一些字段):
quotes
------
id
name
business_quotes
---------------
id
quote_id
business_id
status
对于status
表中的business_quotes
字段,可能的值为:
0
- 引用未解答1
- 引用已解答2
- 报价已订购3
- 引用被拒绝我想检索所有至少一个订单(status = 2
)或的引用,其中所有关联的business_quotes记录被拒绝了。我可以通过以下查询得到一个或另一个。
获取包含订单的所有quotes
:
SELECT quotes.*
FROM quotes
INNER JOIN business_quotes
ON quotes.id = business_quotes.quote_id
WHERE business_quotes.status = 2
GROUP BY quotes.id
让所有quotes
被拒绝所有business_quotes
。
SELECT quotes.*
FROM quotes
INNER JOIN business_quotes
ON quotes.id = business_quotes.quote_id
HAVING SUM(business_quotes.status) = COUNT(business_quotes.id) * 3
我不能做的是在一个查询中混合这两个条件。
在某些情况下,可以简单地将WHERE
条件转换为HAVING
,如此答案中所述:https://stackoverflow.com/a/20900476/1128918。但我不能遵循相同的逻辑,因为status
列不在select
语句中。
答案 0 :(得分:2)
这样的事情应该有效。 select中的聚合是可选的。基本上,您只需要查询具有任何“2”状态的引号,或者具有值为“3”的所有状态。
免责声明:未检查语法错误,我通常的SQL语言是T-SQL,因此可能需要调整。
SELECT
quotes.id,
quotes.name,
SUM(CASE WHEN business_quotes.status = 2 THEN 1 ELSE 0 END) as NumOrdered,
SUM(CASE WHEN business_quotes.status = 3 THEN 1 ELSE 0 END) as NumRefused
FROM
quotes
INNER JOIN business_quotes ON quotes.id = business_quotes.quote_id
GROUP BY
quotes.id,
quotes.name
HAVING
SUM(CASE WHEN business_quotes.status = 2 THEN 1 ELSE 0 END) > 0
OR
SUM(CASE WHEN business_quotes.status = 3 THEN 1 ELSE 0 END)
= COUNT(quotes.id)
答案 1 :(得分:1)
UNION很有用的地方:
SELECT quotes.*
FROM quotes
INNER JOIN business_quotes
ON quotes.id = business_quotes.quote_id
WHERE business_quotes.status = 2
GROUP BY quotes.id
UNION
SELECT quotes.*
FROM quotes
INNER JOIN business_quotes
ON quotes.id = business_quotes.quote_id
HAVING SUM(business_quotes.status) = COUNT(business_quotes.id) * 3
答案 2 :(得分:0)
如果每个报价至少有一个订单,那么您可以使用not exists
检查所有订单是否具有特定状态,并exists
检查是否至少有一个订单具有某种状态
select * from quotes q
where exists (
select 1 from business_quotes bq
where bq.status = 2
and bq.quote_id = q.id
)
or where not exists (
select 1 from business_quotes bq
where bq.status <> 3
and bq.quote_id = q.id
)