#mysql #sql
#mysql #sql
Вопрос:
Есть две таблицы со столбцами, и я делаю базовое соединение по ЛЕВОМУ КРАЮ:
Случай 1
SELECT g_users.id, g_users.username, f_list.user_id
FROM g_users
LEFT JOIN f_list
ON f_list.friend_id = g_users.id
WHERE g_users.username IN ('meme', 'john', 'doe')
AND g_users.id != 4
Все хорошо!
Случай 2, применяемый к тем же записям
SELECT g_users.id, g_users.username, f_list.user_id
FROM g_users
LEFT JOIN f_list ON
f_list.friend_id = g_users.id
WHERE g_users.username IN ('meme', 'john', 'doe')
AND g_users.id != 4
AND f_list.user_id != 4
Я ожидал вернуть записи doe, но он ничего не вернул. Чего мне не хватает?
Комментарии:
1. Ваше использование
GROUP BY
недопустимо. ВSELECT
списке есть столбцы, которые несовместимы со столбцамиGROUP BY
— изf_list
таблицы.2. Не используйте
GROUP BY
withSELECT *
. Такой запрос не имеет смысла и не выполняется нигде, кроме MySQL (может быть разрешен в SQLite). Извиняюсь, вам пришлось изучать SQL таким образом!3. Спасибо за ответ. Я удалил group by. Это все еще не работает. Я обновил вопрос.
4. Если вы НИКОГДА не используете
SELECT *
, вы, вероятно, не ошибетесь.5. A
LEFT JOIN
WHERE
(с условиями, использующими таблицу с левым соединением) =INNER JOIN
. Некоторое время назадWHERE
использовался для неявного соединения!
Ответ №1:
Ах, удивительный мир обработки нулевых значений.
Проблема возникает при выполнении сравнения в вашем предложении WHERE с таблицей, к которой вы присоединяетесь слева. У вас есть этот f_list.user_id != 4 . Для строк, которые не совпадают с вашим соединением по левому краю, это выражение вычисляется, если null != 4, что равно false, потому что это нулевое значение.
У вас есть 2 уникальных совпадающих значения, null и 4, из которых оба исключаются в приведенном выше заявлении, что оставляет вас с 0 строками в результате.
Чтобы получить желаемый результат, вы можете обернуть f_list.user_id в функцию обработки null, такую как COALESCE .
Комментарии:
1. COALESCE не будет работать в этом сценарии, поскольку он все равно вернет значение null для этого условия
2. Подразумевается, что вам нужно будет предоставить как минимум 2 аргумента, такие как COALESCE(user_id, -1) .
Ответ №2:
Если у вас есть ANSI_NULLS ДЛЯ условия сравнения, содержащего нулевое значение, возвращает unknown, а не true или false. Ваше условие и f_list.user_id != 4 не возвращают true для строки doe
Вы можете попробовать запустить
SET ANSI_NULLS OFF
перед тем, как ваш запрос или escape ОБНУЛЯТСЯ
РЕДАКТИРОВАТЬ Как объяснил пользователь, это Mariadb, единственный доступный вариант — экранирование нулей с помощью AND (f_list.user_id != 4 или И f_list.user_id РАВНО НУЛЮ)
Комментарии:
1. Я использую MariaDB, а не MSSQL. Я не могу его отключить
2. Прошу прощения, я не заметил СУБД, которую вы используете. Вам нужно будет выполнить безопасное сравнение с нулем или вручную добавить «или f_list.user_id равно нулю».
3. Мое удовольствие! 🙂