我是SQL的新手,无法构建查询:
我有三张桌子:
杂志店的顾客:
Customer(cid, name)
杂志
Magazine(mid, topic)
杂志的订阅:
Subscribes(cid, mid)
如何构建一个查询,以显示仅订阅一本杂志的客户,条件是所有其他订阅该杂志的客户都订阅了至少一本其他杂志?
我设法构建了一个查询(不确定是否绝对正确),该查询显示只订阅了一本杂志并且卡在此处的客户:
select customer.cid, customer.name, count(subscribes.mid)
from subscribes, customer
where subscribes.cid=customer.cid
group by customer.cid
having count(subscribes.mid)=1
答案 0 :(得分:3)
如何构建一个查询,向我展示客户 订阅了只有一本杂志,条件是其他所有 订阅该杂志的客户至少订阅了一个 其他杂志?
你有正确的想法一步一步地采取它。
客户只订阅了一本杂志
SELECT cid
FROM subscribes
GROUP BY cid
HAVING COUNT(mid) = 1
客户订阅了两本或更多杂志
SELECT cid
FROM subscribes
GROUP BY cid
HAVING COUNT(mid) > 1
客户及他们订阅的杂志数量
SELECT cid, count(mid) as s_count
FROM subscribes
GROUP BY cid
所以
WITH cust_and_count AS
(
SELECT cid, count(mid) as s_count
FROM subscribes
GROUP BY cid
)
SELECT cust_and_count.cid, s1.mid
FROM cust_and_count -- with the where below this gives us all users subscribed to a single mag
-- Get the magazine of users that have one subscription
JOIN subscribes s1 on cust_and_count.cid = s1.cid
-- Join that magazine back to who subscribes exclude our starting guys
JOIN subscribes s2 on s1.mid = s2.mid and s2.cid != cust_and_count.cid
-- Join back to our counts and make sure it is greater than 1
JOIN cust_and_count c2 on s2.cid = c2.cid and c2.s_count > 1
WHERE cust_and_count.s_count = 1
请注意,表名通常不是复数 - 所有表都有行,您通常会根据单个元素的名称来命名,所以客户,杂志,订阅都在您的情况下。
答案 1 :(得分:1)
以下查询选择仅订阅1本杂志的所有客户:
//equivalent to assembly
//MOV EAX sys_call_no
//INT 0x80
void* interrupt(int service, void* args, void* ret)
{
kernel::intr_queue.push_back_syncd(interrupt_context(){kernel::int_vector[service], args, ret});
waitForServiceCompleted();
return ret;
}
//in kernel thread
while(true)
{
while(!intr_queue.isEmpty())
{
auto context = intr_queue.pop();
context.ret = context.func(context.args);
notifyDone();
}
}
此查询选择SELECT *
FROM Subscribes
GROUP BY cid
HAVING COUNT(Subscribes.mid) = 1
杂志C
以外的所有客户,只有1个订阅:
M
我相信,这会做你在问题中提出的问题:
SELECT 1
FROM Subscribes
WHERE mid = M
AND cid != C
AND EXISTS (SELECT 1
FROM Subscribes
WHERE cid = Subscribes.cid
AND COUNT(mid) <= 1)
说明:
SELECT *
FROM Subscribes
GROUP BY cid
HAVING COUNT(Subscribes.mid) = 1 as SingleSubs
AND NOT EXISTS (SELECT 1
FROM Subscribes
WHERE mid = SingleSubs.mid
AND cid != SingleSubs.cid
AND EXISTS (SELECT 1
FROM Subscribes
WHERE cid = Subscribes.cid
AND COUNT(mid) <= 1))
答案 2 :(得分:0)
必须归功于@Hogan ......
小提琴:
http://sqlfiddle.com/#!6/860e7/4
代码:
;WITH cust_and_count AS
(
SELECT cid, count(mid) as s_count
FROM subs
GROUP BY cid
)
SELECT distinct c1.cid
FROM cust_and_count c1
JOIN subs s1 on c1.cid = s1.cid
JOIN subs s2 on s1.mid = s2.mid and s2.cid != c1.cid and s1.mid >1
WHERE c1.s_count = 1
答案 3 :(得分:0)
如果问题正确,那么答案是:
select cid from subscribers
group by cid
having count(mid) = 1
,因为:
如何构建一个显示客户的查询 订阅了只有一本杂志,条件是其他所有 订阅该杂志的客户至少订阅了 另一本杂志?
查询返回仅订阅1个杂志的订阅者。您的第二个条件会自动应用,因为其他客户将处于结果集中。即如果其他客户订阅了输出中的某个杂志而该客户没有输出,这意味着他订阅了更多的杂志,包括当前的杂志。
如果您想用同一杂志排除成对客户,请:
select max(cid)
from(select cid, max(mid) mid from subs
group by cid
having count(mid) = 1) t
group by mid
having count(cid) = 1