我的表是:
customer(cid,name,city,state)
orders(oid,cid,date)
product(pid,productname,price)
lineitem(lid,pid,oid,number,totalprice)
我想选择城市'X'的所有客户购买的产品。这意味着我需要交叉所有居住在城市'X'的客户购买的产品
示例:如果有3个客户c1,c2和c3我的答案是c1.product(intersect)c2.product(intersect)c3.product
我只想使用where exists
或where not exists
来实现这一点,因为我需要编写关于where not in
或where in
不可用的关系演算。我可以部分查询是这样的:
select
*
from
product p,
lineitem l,
customer c1
where
exists(
select
*
from
customer c,
orders o
where
o.cid=c.cid and
c.city='X' and
l.oid=o.oid and
l.pid=p.pid and
c1.cid=c.cid)
以上查询为我提供了生活在X市的所有客户的pid,cid,oid,lid,totalprice,city,productname。现在我需要弄清楚如何选择所有客户共有的产品。
注意:
我无法使用任何聚合函数,因为它在关系演算中不可用。我有一个使用聚合函数的工作查询,这是
select
p.productname
from
product p,
orders s,
lineitem l,
customer c
where
l.pid=p.pid and
l.oid=s.oid and
c.cid=s.cid and
c.city='X'
group by
p.productname
having
count(distinct c.cid)=(select count(*) from customer c1 where c1.city='X')
如果有人可以在不where exists
和where not exists
的{{1}}或count
表单中转换上述查询,那就没问题了。
我确信它可以完成,因为我可以在关系代数中这样做,并且根据Codd's theorom元组关系演算和关系代数在逻辑上是等价的,并且在一个中表达的任何查询都可以在其他中表达。关系代数和关系演算不支持聚合函数,查询可以在没有聚合函数的情况下用sql表示。
答案 0 :(得分:4)
这是我的答案。
我在http://www.sqlfiddle.com/#!2/f2fb85/1创建了一个sqlfiddle,所以你可以尝试一下。
查询是:
SELECT p.*
FROM product p
WHERE NOT EXISTS (
SELECT c.cid
FROM customer c
WHERE NOT EXISTS (
SELECT l.lid
FROM lineitem l
JOIN orders o ON o.oid = l.oid
WHERE l.pid = p.pid
AND o.cid = c.cid
)
AND c.city = 'X'
) AND EXISTS (
SELECT c.cid
FROM customer c
WHERE c.city = 'X'
)
答案 1 :(得分:1)
根据您的评论,我已将此前的答案替换为不使用IN
的答案。这个使用多级相关子查询:
select p.*
from product p
where exists (
select *
from customer c
where c.city = 'x'
and exists (
select *
from lineitem l
where l.pid = p.pid
and exists (
select *
from orders o
where o.oid = l.oid
and o.cid = c.cid
)
)
)
and not exists(
select *
from customer c
where c.city = 'x'
and not exists (
select *
from lineitem l
where l.pid = p.pid
and exists (
select *
from orders o
where o.oid = l.oid
and o.cid = c.cid
)
)
)
答案 2 :(得分:1)
ANSI-Sql缺乏集合论universal quantifier,你需要use rewrite roles to get existential quantifier:
∀ Universal quantifier (For all . . .)
∃ Existential quantifier (There exists . . .)
示例:
(∀c ∈ CUSTOMER)
⇔ /*Add double negation */
¬¬(∀c ∈ CUSTOMER)
⇔ /*Bring one negation into the quantification, quantifier changes */
¬(∃c ∈ CUSTOMER)
Sql翻译:
SELECT p.*
FROM product p
WHERE NOT EXISTS (
SELECT c.cid
FROM customer c
WHERE c.city = 'X'
AND NOT EXISTS
(
SELECT o.oid
FROM orders o
JOIN lineitem l ON l.oid = o.oid
WHERE l.pid = p.pid
AND o.cid = c.cid
)
)
答案 3 :(得分:0)
select * from product p where not exists(
select *
from customer c
where c.city = 'x'
and not exists (
select *
from lineitem l
where l.pid = p.pid
and exists (
select *
from orders o
where o.oid = l.oid
and o.cid = c.cid
)
)
)
关系演算:
{T| ∃pЄproduct (¬(∃cЄcustomer(c.city="Newark")^¬(∃lЄlineitem(l.pid=p.pid)^∃oЄorders(o.oid=l.oid^o.cid=c.cid))))}
关系代数: