2016-11-25 6 views
2

У меня есть следующий запрос, в котором соединяется несколько таблиц. Одна из этих таблиц - profile_img. В этой таблице представлены изображения профилей для пользователей, которые их загрузили, в противном случае они даются profile_images/default.jpg, а пользователь не находится в таблице profile_img, поэтому мне нужен случай сортировки, чтобы проверить, не находятся ли они в этой таблице, а затем установить их профиль изображение по умолчанию.Использование else в запросе SQL

Вот мой вопрос.

SELECT f.*, u.*, p.* 
    FROM friends f 
    LEFT JOIN 
     profile_img p 
     ON p.user_id = f.friend_one 
    JOIN 
     users u 
     ON u.id = f.friend_one 
    WHERE f.friend_two = ? AND f.status = ? AND 
     p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id) 

Я попытался ,coalesce(p.img, 'profile_images/default.jpg') as img, чтобы попытаться получить результат, но это не помогло.

В другом запросе:

(case when p.img <> '' then p.img 
else 'profile_images/default.jpg' 
end) as img 

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

ответ

1

@marekful является правильным в использовании IFNULL(), но есть еще одно исправление то будет необходимо.

В вашем предложении where вы ссылаетесь на p.id =. Поскольку p будет null, если для этого пользователя нет строк profile_img, вся строка будет исключена из результатов из-за сравнения с NULL.

Этот запрос учитывает нулевые поля p.id и включает их в любом случае, разрешая p.id, когда его значение равно null. Теперь p.image_url будет null, и метод ifnull() будет отвечать «default.png» для этих строк.

SELECT f.*, u.*, p.*, IFNULL(p.image_url, 'default.png') AS profile_pic 
FROM friends f 
LEFT JOIN 
    profile_img p 
    ON p.user_id = f.friend_one 
JOIN 
    users u 
    ON u.id = f.friend_one 
WHERE 
    f.friend_two = ? 
    AND f.status = ? 
    AND (p.id is null or p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id)) 

Вы также можете сделать это без предложения OR, добавив подзапрос в предикат ON. Подзапрос затем разрешается перед соединением.

SELECT f.*, u.*, p.*, IFNULL(p.image_url, 'default.png') AS profile_pic 
FROM friends f 
JOIN 
    users u 
    ON u.id = f.friend_one 
LEFT JOIN 
    profile_img p 
    ON p.user_id = f.friend_one and p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id)  
WHERE 
    f.friend_two = ? 
    AND f.status = ? 

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

+0

Спасибо. Это сделал трюк. Не могли бы вы рассказать мне, почему работал? Что такое рассуждения? – Paul

+1

ifnull, как и coalesce, возвращает другое значение, когда поле его тестирования равно null. В этом случае поле p.image_url является нулевым для пользователей, у которых нет изображений, поэтому вместо него возвращается default.png. Функционально это эквивалентно: case, когда p.image_url имеет значение null, а затем 'default.png' else p.image_url end as profile_pic – serverSentinel

1

Вы можете выбрать поле, значение которого будет установлено условно, например. используя IFNULL()

SELECT f.*, u.*, p.*, IFNULL(p.image_url, 'default.png') AS profile_pic 
FROM friends f 
LEFT JOIN 
    profile_img p 
    ON p.user_id = f.friend_one 
JOIN 
    users u 
    ON u.id = f.friend_one 
WHERE f.friend_two = ? AND f.status = ? AND 
    p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id) 
+0

Я изменил его на 'IFNULL (p.img, 'profile_images/default.jpg') AS profile_pic', но не повезло. – Paul

+0

Возможно, другой JOIN также должен быть LEFT JOIN или первым должен быть ПРАВИЛЬНЫЙ JOIN, так как p table после этого – Mihai

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