SQL Case столбец null переопределяет селекторы
Я хочу создать инструкцию SQL select, которая объединит несколько таблиц и результаты yeidl. По существу, у меня есть две таблицы, которые независимы друг от друга. Одна таблица содержит пользователей (которые, как предполагается, имеют самую актуальную и правильную информацию), и у меня есть размещенный держатель таблицы под названием Игроки. Таблица заполнитель в столбце идентификатор пользователя, который имеет значение как null. когда пользователь распознается как игрок, то нулевое значение userID заменяется уникальным идентификатором пользователя.
В этом случае я хочу использовать SQL для проверки, если userID равен NULL. я написал следующее утверждение, которое не работает
SELECT
teams.*, players.number, players.position, players.userId,
CASE WHEN players.userId IS NULL THEN players.id ELSE userPlayer.id END AS playerId,
CASE WHEN players.userId IS NULL THEN players.firstName ELSE userPlayer.firstName END AS firstName,
CASE WHEN players.userId IS NULL THEN players.lastName ELSE userPlayer.lastName END AS lastName,
CASE WHEN players.userId IS NULL THEN players.email ELSE userPlayer.email END AS email
FROM teams
LEFT JOIN players ON players.teamId = teams.id
LEFT JOIN users AS userPlayer ON userPlayer.id= players.userId
WHERE teams.id = (:t)
Это кажется очень неэффективным. Есть ли лучший способ?
Спасибо
3 ответа:
Начнем с того, что
userPlayer.id
никогда не отличается отplayers.userId
(либо оба являются чем-то, либо оба равны нулю), поэтому вы можете обойтись без этого выражения.Также используйте
coalesce()
вместоcase when x is null
для ясности и краткости:SELECT teams.*, players.number, players.position, players.userId AS playerId, COALESCE(userPlayer.firstName, players.firstName) AS firstName, COALESCE(userPlayer.lastName, players.lastName) AS lastName, COALESCE(userPlayer.email, players.email) AS email FROM teams LEFT JOIN players ON players.teamId = teams.id LEFT JOIN users AS userPlayer ON userPlayer.id = players.userId WHERE teams.id = (:t)
Вы можете создать представление, в котором удобно выбирать команды по их идентификатору. В этом случае можно оптимизировать, потому что если игроки.имя пользователя имеет значение NULL, то все ценности пользователей являются null (т. к. уехал). Таким образом, вы можете создать объединение, если у вас есть много нулевых записей, это может быть полезно:
SELECT teams.*, players.number, players.position, players.userId AS playerId, players.firstName, players.lastName, players.email FROM teams LEFT JOIN players ON players.teamId = teams.id WHERE players.userId IS NULL OR NOT EXISTS(SELECT * FROM users WHERE users.id = players.userId) UNION SELECT teams.*, players.number, players.position, players.userId AS playerId, COALESCE(userPlayer.firstName, players.firstName) AS firstName, COALESCE(userPlayer.lastName, players.lastName) AS lastName, COALESCE(userPlayer.email, players.email) AS email FROM teams INNER JOIN players ON players.teamId = teams.id INNER JOIN users AS userPlayer ON userPlayer.id = players.userId
Если ваши " игроки.userId " PK, вы можете попробовать это:
SELECT teams.*, players.number, players.position, players.userId, ISNULL(players.id, userPlayer.id) AS playerId, ISNULL(players.firstName, userPlayer.firstName) AS firstName, ISNULL(players.lastName, userPlayer.lastName) AS lastName, ISNULL(players.email, userPlayer.email) AS email FROM teams LEFT JOIN players ON players.teamId = teams.id LEFT JOIN users AS userPlayer ON userPlayer.id= players.userId WHERE teams.id = (:t)