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 3

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)