SQL Case列为null重新定义选择器

时间:2015-07-21 23:01:35

标签: sql join left-join

我想创建一个SQL select语句,它将加入几个表和yeidl结果。基本上我有两个彼此独立的表。一个表包含用户(假设它具有最新和正确的信息),并且我有一个名为player的放置持有者表。占位符表有一个标记为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)

这似乎非常低效。还有更好的方法吗?

感谢

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

您可以创建一个视图,您可以根据其ID轻松选择团队。在这种情况下,可以进行优化,因为如果players.userId为null,则user的所有值都为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

答案 2 :(得分:0)

如果你的“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)