2016-12-12 6 views
1

Сегодня я чувствую себя глупо, но у меня есть запрос, который я хочу написать, но я чувствую, что это может быть вне досягаемости.Можно ли написать этот вопрос - чего я не вижу?

Я попытаюсь упростить задачу только ради простоты.

У меня есть таблица, как этот

[Table A] 
ID | Class | Name 
0  A  Sarah 
1  B  Tom 
2  C  Bob 
3  A  Jen 
4  A  John 
5  A  Jack 
6  B  Name1 
7  B  Jack 
8  B  Bob 

мне нужно, чтобы получить все записи (фактические записи не группируются по) для всех людей, которые разделяют один и тот же класс, но со следующими ограничениями:

Только получите мне записи, где Джен, Джек & Джон разделяют один и тот же класс (только те 3 нет и не дублируют).

Это означает, что записи будут приходить в виде наборов 3.

Таким образом, в приведенном выше примере я хотел бы получить

3  A  Jen 
4  A  John 
5  A  Jack 

До сих пор я получил:

SELECT Class, Name, COUNT(*) 
FROM TableA 
GROUP BY Class, Name 
HAVING COUNT(*) = 3 

Но в дополнение к этому не работает правильно, я не могу указать, что записи должны иметь имена Джен, Джек и Джон и ничего больше.

EDIT: я был в состоянии сделать это, используя внутренний запрос, но это немного slow..If кто-нибудь знает более оптимальный, пожалуйста, дайте мне знать:

SELECT .... 
FROM TableA t1 
join TableA t2 on t1.class = t2.class 
WHERE t1.name = 'Jen' AND t2.name = 'John' 
AND t1.class IN(SELECT class FROM TableA t3 WHERE t3.name = 'Jack'))) 

Я мог бы, вероятно, включили t3 с исходный запрос, но я предпочитаю этот способ для удобочитаемости.

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

+0

Требование не ясное - как только станет ясно, возможно, написать запрос будет проще. Вы действительно ищете для всех классов со следующими свойствами: (1) Джен, Джон и Джек все берут этот класс; (2) Никто не принимает этот класс? Если это так, 'select * from tableA, где класс in (select class from ... where ...)' должен находиться в правильном направлении. – mathguy

+0

@mathguy - без проблем - отредактирует вопрос. – AngelicCore

+0

В отредактированной форме вы больше не спрашиваете, что класс будет принимать только 3 ученика, не более, не менее. (Не менее понятно, но вы удалили «больше».) И действительно, вы добавили ряд с Сарой, взяв класс A, но результат не показывает ее. Просьба уточнить. – mathguy

ответ

2

Если вы после классов, в которых ваши трое людей поделились одним и тем же классом, даже если присутствовали другие люди, то вы были довольно близки к вашему запросу, за исключением того, что вам не было предложено предложение WHERE, чтобы ограничить строки имена, которые вас интересовали.

Плюс, видя, что вы не хотели свертывать строки ("the actual records, not grouped by"), то вы после аналитики COUNT, а не агрегат.

Поэтому то, что вы после этого будет выглядеть примерно так:

WITH table_a AS (SELECT 0 ID, 'A' CLASS, 'Sarah' NAME FROM dual UNION ALL 
       SELECT 1 ID, 'B' CLASS, 'Tom' NAME FROM dual UNION ALL 
       SELECT 2 ID, 'C' CLASS, 'Bob' NAME FROM dual UNION ALL 
       SELECT 3 ID, 'A' CLASS, 'Jen' NAME FROM dual UNION ALL 
       SELECT 4 ID, 'A' CLASS, 'John' NAME FROM dual UNION ALL 
       SELECT 5 ID, 'A' CLASS, 'Jack' NAME FROM dual UNION ALL 
       SELECT 6 ID, 'B' CLASS, 'Name1' NAME FROM dual UNION ALL 
       SELECT 7 ID, 'B' CLASS, 'Jack' NAME FROM dual UNION ALL 
       SELECT 8 ID, 'B' CLASS, 'Bob' NAME FROM dual) 
-- End of mimicking your table_a with data in it 
-- See query below: 
SELECT ID, 
     CLASS, 
     NAME 
FROM (SELECT ID, 
       CLASS, 
       NAME, 
       COUNT(NAME) OVER (PARTITION BY CLASS) name_cnt 
     FROM table_a 
     WHERE NAME IN ('Jen', 'Jack', 'John')) 
WHERE name_cnt = 3; 

Вы заметите, что аналитические функции не имеют эквивалентное HAVING положения, что агрегатные функции делать, а это значит, что вы должны сделать фильтрация во внешнем запросе. Надеюсь, вы увидите, что мой запрос похож на ваш?

+0

. Я подозреваю, что OP является учеником, и они, возможно, еще не изучили аналитические функции (поэтому в комментарии я предложил вместо этого подзапрос) , – mathguy

+0

На самом деле я инженер-программист, но тот, кто полагался на код (и linq) намного больше, чем SQL, - и это результат :) – AngelicCore

+0

Спасибо, Boneist. Я буду играть со своим sql и дам вам знать, как он поступил. – AngelicCore

 Смежные вопросы

  • Нет связанных вопросов^_^