2015-11-30 2 views
2

Я новичок в SQL и возникли проблемы построить запрос:Создание вложенного запроса в 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 
+2

показать, что вы сделали до сих пор. – Hogan

+0

Я обобщил вопрос, чтобы иметь менее нерелевантные детали ... Мое решение - беспорядок. –

+1

ваше решение может быть беспорядком, но ответов не существует - это не сложно, мы все можем это сделать, но мы хотим видеть которые вы пробовали, прежде чем тратить время на выполнение вашей работы. – Hogan

ответ

1

Следующий запрос выбирает все клиенты подписались только один журнал :

SELECT * 
FROM Subscribes 
GROUP BY cid 
HAVING COUNT(Subscribes.mid) = 1 

Этот запрос выбирает все, кроме C клиентов для журнала M с 1 подписки:

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)) 

Объяснение:

SELECT (All cid, mid with 1 subscription) as SingleSubs 
WHERE NOT EXISTS (All customers other than SingleSubs.cid with 1 subscription) 
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 

примечание, имена таблиц обычно не множественные - все таблицы имеют строки, которые вы обычно называете им одним и тем же именем, так что клиент, журнал, подписка в вашем случае.

+0

«выбрать из» - это синтаксическая ошибка – tshoemake

+0

@tshoemake - хороший момент - забыл вернуться и поставить там что-то интересное. – Hogan

+0

Правильный ответ – tshoemake

0

Должен отдать @Hogan ...

Fiddle:

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 
+0

Ohh man 6 2 - это строка той же мощности, что и 4 2. Почему вы думаете, что 6 - единственный правильный человек ? –

+0

@GiorgiNakeuri # 1 удовлетворенное условие: C2, C4, C5, C6 все подполюсны только одному магниту. C2 является подслоем для mag 1, но C5 также ТОЛЬКО подповерхность к магниту 1. C5 подпадает под магнит 1, но C2 также ТОЛЬКО подсловляется магнитом 1. C4 подпадает к магниту 2, но ни у кого нет (мы нуждаемся в подполе клиентов к mag 2 И еще один маг для того, чтобы C4 мог пройти квалификацию). # 2 выполнено: C6 подсловляется магнитом 3. C1 и C3 оба подполяны к магне 3, а BOTH подчиняются другому магните (mag 1). C6 - единственный результат. – tshoemake

+0

Отлично, вы только что изменили 2 на 3. Я изменил 3 на 2, и ваш выбор вернется 4 и 6. –

0

Если вопрос правильно спросил тогда ответ:

select cid from subscribers 
group by cid 
having count(mid) = 1 

потому что:

Как создать запрос, который будет показывать клиентам, которые подписались только один журнал с условием, что все остальные клиенты подписались на этот один журнал подписаны, по крайней мере одного другой журнал?

Запрос возвращает подписчиков, которые подписаны только на 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 
Смежные вопросы