2016-06-29 3 views
1

У меня есть запрос, который объединяет несколько таблиц (3 или 4) и получает результаты, как ожидалось.SELECT все EXCEPT результаты в подзапросе

SELECT DISTINCT test_title, stt_id FROM student_tests 
LEFT JOIN student_test_answers ON sta_stt_num = stt_id 
JOIN tests ON stt_test_id = test_id 
WHERE student_test_answer_id IS NULL 

У меня есть еще один запрос, который показывает другой набор данных, в основном это:

SELECT test_id, COUNT(*) AS theCount FROM tests 
    JOIN test_questions ON test_id= tq_test_id 
    WHERE type= 'THE_TYPE' 
    GROUP BY test_id 
    HAVING theCount = 1 

Поэтому в основном я хочу, чтобы НЕ включать результаты этого второго запроса в первом. test_id будет полями объединения.

Я пробовал, ГДЕ НЕ СУЩЕСТВУЕТ (-в приведенном выше запросе -), но который не возвращает никаких результатов, что неверно. Я также попробовал «NOT IN()»

Есть ли лучший способ сделать это?

+0

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

+0

напишите пожалуйста свои настоящие запросы, образцы данных и ожидаемый результат. ваше объяснение не очень понятно, и ваш запрос также не ясен: 'test_id = tq_test_id' - мы понятия не имеем, какая таблица принадлежит этим столбцам. – Alex

+1

Как именно вы пытались' NOT IN() '? Если вы хотите использовать этот запрос, так как подзапрос не нужен theCount в наборе результатов. – Philipp

ответ

3

попробовать что-то вроде этого:

(SELECT test_id, COUNT(*) AS theCount FROM tests 
JOIN test_questions ON test_id= tq_test_id 
WHERE type= 'THE_TYPE' 
GROUP BY test_id 
HAVING theCount = 1) outer 
LEFT JOIN (
     [OtherQuery] 
) a ON outer.test_id = a.test_id 
WHERE a.test_id IS NULL 
+0

Я уверен, что это то, что мне нужно. – KickingLettuce

+0

Я не знаю, каков его запрос, но структура его, похоже, работает. Я думаю, что другие, возможно, сделали то же самое.Конечно, я добавил это как «LEFT JOIN (ANSWER)» в свой основной запрос. Выше - только соответствующая часть, в которой я нуждался. – KickingLettuce

+0

@Alex Sarcasm Думаю? Я скажу, что остальные, похоже, уделяли ему больше времени и форматированию. Но я думаю, что я выберу ответ, который сработал для меня. Сообщество просто поддержит лучший, который я всегда ищу. – KickingLettuce

0

Что именно является второй запрос? Я вижу только один запрос здесь, и никакого подзапроса. Кроме того, будет полезной sqlfiddle вашей точной схемы.

Во всяком случае, я думаю, вы хотите, чтобы какой-то левый исключающий присоединился. Это выглядит примерно так:

select  test.test_id, count(*) as theCount 
from  tests test 
join  test_questions tq 
on   tq.test_id = test.test_id 
left join tests excluded_test 
on   excluded_test.test_id = test.test_id 
where  tq.type = 'THE_TYPE' 
and  << Some condition that explains what excluded_test is >> 
and  excluded_test.test_id is null 

EDIT: Да, есть определенно много деталей, пропавших без вести от первоначального вопроса (который был в каком-то смысле починенная), и которые до сих пор пропавшими без вести. Знание полной таблицы-структуры вашего примера важно здесь, поэтому трудно дать хороший конкретный ответ.

1

Как написано в комментарии, вы должны быть в состоянии сделать это следующим образом:

SELECT 
    DISTINCT test_title, 
    olc_stt_i_num 
FROM 
    student_tests 
LEFT JOIN 
    student_test_answers 
     ON olc_sta_i_stt_num = olc_stt_i_num 
INNER JOIN 
    ol_class_tests 
     ON stt_test_num = test_num 
WHERE 
    student_test_answer_id IS NULL 

    -- added this: replace test_id with real column 
    AND ***test_id*** NOT IN (
     SELECT 
     test_id 
     FROM 
     tests  
     JOIN 
     test_questions 
      ON test_id= tq_test_id  
     WHERE 
     type= 'THE_TYPE'  
     GROUP BY 
     test_id  
     HAVING 
     COUNT(*) = 1 
    ) 
+1

Мне просто интересно: hwo знаете ли вы, что столбец 'test_id' существует в' student_tests' или 'student_test_answers' или' ol_class_tests'? я что-то пропустил? – Alex

+0

Нет, это как раз заполнитель для фактического столбца с идентификатором, отметьте его как таковой. OP подразумевает, что есть такой столбец, что только количество (*) в выборе подзапроса испортило его запрос – Philipp

1

Вот мой ответ. Left outer Join дает вам участника (тест). Если в test_questions нет совпадений, он все равно будет возвращать тестовые строки, но null для test_questions. Поэтому, если вы затем ищете какой-либо test_question.test_id, который является нулевым, вы получите то, что ищете.

Я также был бы конкретным в вашем выражении count, а не счет (*), чтобы гарантировать, что mysql знает, что вы действительно хотите сосчитать.

create database test; 
use test; 

create table test 
(
    test_id int, 
    `the_type` varchar(20) 
); 

create table test_questions 
(
    test_question_id int, 
    test_id int, 
    `the_type` varchar(20) 
); 

insert into test values (1, 'history'); 
insert into test values (2, 'chemistry'); 
insert into test values (3, 'reading'); 

insert into test_questions values (1, 1, 'hard question'); 
insert into test_questions values (2, 1, 'medium question'); 
insert into test_questions values (3, 2, 'hard question'); 
insert into test_questions values (4, 2, 'easy question'); 

select * from test; 
select * from test_questions; 

select t.test_id, count(distinct t.test_id) 
from test t 
left outer join test_questions tq on tq.test_id = t.test_id 
where 
    tq.test_id is null 
group by 
    t.test_id