SQL 案例列为空重新定义选择器

SQL Case column is null redefine selectors

我想创建一个 SQL select 语句,它将连接一些 tables 和 yeidl 结果。本质上,我有两个相互独立的 table。一个 table 包含用户(假设拥有最新和正确的信息),我有一个名为 players 的持有人 table。占位符 table 有一个标记为 userID 的列,该列设置为 NULL。当用户被识别为玩家时,userID 的 NULL 值将替换为用户的唯一 ID。

这种情况下我想使用 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)

这看起来效率很低。有没有更好的方法?

谢谢

首先,userPlayer.idplayers.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)

您可以创建一个视图,您可以在其中轻松地 select 按 ID 显示团队。在这种情况下,可以进行优化,因为如果 players.userId 为空,则 user 的所有值都为空(因为左连接)。所以你可以创建一个联合,如果你有很多空条目,它可能是有益的:

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

如果你"players.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)