2015-07-21 1 views
3

Я хочу создать оператор выбора SQL, который будет ПРИСОЕДИНИТЬ несколько таблиц и результаты yeidl. По сути, у меня есть две таблицы, которые независимы друг от друга. Одна таблица содержит пользователей (которые, как предполагается, имеют самую актуальную и правильную информацию), и у меня есть таблица с владельцем, которая называется игроком. Таблица заполнителя имеет столбец с меткой userID, который установлен как NULL. когда пользователь распознается как игрок, значение NULL для идентификатора пользователя заменяется уникальным идентификатором пользователя.SQL-столбец столбца - это нулевые селекторы переопределения

В этом случае я хочу использовать 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) 

Это кажется очень неэффективным. Есть ли способ лучше?

благодаря

+0

ли вам только хотите вернуть результаты, в которых «Player» имеет соответствующий «Пользователь»? Или вы хотите вернуть * все * игроков, а иногда 'userId' будет' NULL', а иногда нет? – ragerory

+0

Я хочу записать пользователя, когда у игрока есть соответствующий пользователь –

+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) 
+0

Это утверждение неверно. «Для начала userPlayer.id никогда не отличается от player.userId« AS players.userId может быть NULL, тогда как userPlayer.id всегда будет уникальным буквенно-цифровым значением –

+0

@bushbrigade, но из-за условия соединения, если player.userId равно null, для пользователей не будет присоединения, поэтому левое соединение будет возвращать значения null для всех столбцов пользователей. Таким образом, мой ответ верен: для любой заданной строки либо player.userId, и users.id имеют одно и то же (не нулевое) значение, или оба они равны нулю. – Bohemian

0

Вы могли бы создать представление, где можно с комфортом выбрать команды по их идентификатору. В этом случае можно оптимизировать, поскольку если player.userId имеет значение 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 
0

Если «players.userId» ПК, вы можете попробовать это:

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) 
Смежные вопросы