2015-11-12 2 views
0

Мне нужно скомпоновать запрос LEFT JOIN с запросом NOT IN и должен получить значения результата из этих запросов. Я получаю правильные результаты при использовании этих двух запросов отдельно.MySql как объединить запрос LEFT JOIN с запросом NOT IN

У меня есть две таблицы, вероятно user и answer

user стол

user_id 
1 
2 
3 
4 
5 

answer стол

user_id  date 
1   2015-10-15 21:23:14 
2   2015-10-15 20:23:14 
3   2015-11-11 16:23:14 

LEFT JOIN запрос:

SELECT user.user_id 
FROM user 
LEFT JOIN answer 
    ON user.user_id = answer.user_id 
WHERE DATEDIFF(NOW(),answer.date) > 5 

Этот запрос возвращает результат user_id 1,2.

NOT IN запрос:

SELECT user.user_id 
FROM user 
WHERE user.user_id NOT IN (SELECT answer.user_id FROM answer) 

Этот запрос возвращает результат user_ids 4, 5.

мне нужно, чтобы объединить эти два запроса в один запрос, поэтому я попытался с этими двумя ниже запросов:

SELECT user.user_id 
FROM user 
LEFT JOIN answer 
    ON user.user_id = answer.user_id 
WHERE (DATEDIFF(NOW(),answer.date) > 5 
    AND user.user_id NOT IN (SELECT answer.user_id FROM answer)) 

и

SELECT user.user_id 
FROM user 
LEFT JOIN answer 
    ON user.user_id = answer.user_id 
WHERE user.user_id NOT IN (SELECT answer.user_id FROM answer) 
    AND DATEDIFF(NOW(),answer.date) > 5 

Но эти возвратные пустые user_id.

Редактировать

Ожидаемый результат должен содержать значения 1,2,4,5

+2

Что вы ожидаете увидеть как выход? –

+0

не должно быть 'WHERE DATEDIFF (NOW(), answer.date) <5'? – joop

ответ

2

Если значение собирается объединить 2 выбор вместе
Попробуйте Союз Все/Союз:

SELECT * FROM 
(
SELECT [WITH YOUR LEFT JOIN STATEMENT] 
UNION 
SELECT [WITH YOUR NOT IN STATEMENT] 
) ResultTABLE 
+0

Так мы эмулировали 'LEFT JOINS' в прошлом, прежде чем SQL92 представила их. – joop

1

Если вы ссылаетесь на таблицу ответов в WHERE, значение answer.date будет ограничено значением, отличным от NULL, так как LEFT JOIN будет вести себя как обычное соединение. Перемещение условия к условию ON получить все пользователей, плюс возможно совпадающие строки в answers:

SELECT user.user_id 
FROM user u 
LEFT JOIN answer a ON u.user_id = a.user_id 
        AND DATEDIFF(NOW(),a.date) < 5 
    ; 

Edit: после редактирования вопроса он появится OP хочет присоединившихся записи с несуществующим ответом или ответом.дата слишком старый/молодой:

SELECT user.user_id 
FROM user u 
LEFT JOIN answer a ON u.user_id = a.user_id 
WHERE a.date IS NULL    -- no answer record 
    OR DATEDIFF(NOW(),a.date) > 5 -- too old answer record 
    ; 

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

SELECT user.user_id 
FROM user u 
WHERE NOT EXISTS (
    SELECT * FROM answer a 
    WHERE a.user_id = u.user_id 
    AND DATEDIFF(NOW(), a.date) <= 5 
    ); 
+1

I.e. с условием таблицы ответов в предложении WHERE, LEFT JOIN выполняет как обычный INNER JOIN. – jarlh

+0

Точно! (Я добавлю, что) – joop

+0

@joop ваш отредактированный ответ возвращает '1,2,4,5', но мне нужно' 3,4,5' – Manoj

1

Ваш запрос правильный путь, но вы должны просто заменить AND с OR:

SELECT user.user_id 
FROM user 
LEFT JOIN answer 
    ON user.user_id = answer.user_id 
WHERE user.user_id NOT IN (SELECT answer.user_id FROM answer) 
    OR DATEDIFF(NOW(),answer.date) > 5 

H Если вы можете найти рабочее решение: http://sqlfiddle.com/#!9/2519b/5/0

+1

С условием таблицы ответов в предложении WHERE LEFT JOIN выполняется как обычный INNER JOIN, по крайней мере частично. – jarlh

+0

@sebastianbrosch, ваш ответ возвращает '1,2,4,5' вместо' 3,4,5' – Manoj

+0

извините, что мой запрос 'left join' возвращает значения' 1,2', но я думал, что '3' в одиночку , – Manoj