Как мне присоединиться к третьей таблице в моем операторе SQL, которая возвращает COUNT, не теряя 0 элементов? - PullRequest
0 голосов
/ 23 августа 2010

Продолжение этого вопроса Мне нужен оператор SQL, который возвращает число строк в таблице с определенным значением.

Мы остановились с SQL-оператором следующим образом ...

   SELECT t.teamid,
          t.teamname,
          COALESCE(COUNT(p.playerid), 0) AS playercount,
          t.rosterspots
     FROM TEAMS t
LEFT JOIN PLAYERS p ON p.teamid = t.teamid
 GROUP BY t.teamid, t.teamname, t.rosterspots

Мне нужно добавить еще одно ограничение. ЧТО, ЕСЛИ игрокам необходимо сдать медицинский экзамен, прежде чем они начнут засчитываться в счет «playercount»?

Я представлю таблицу.

MedicalTests
PlayerId  PassedMedical
1         1
2         0
3         1
4         1

Где "PassedMedical" - это бит (1 = true).

А также добавьте еще 1 строку данных в таблицу команд.

TeamId    Team Name
3         Toronto Rapters

Таким образом, у меня есть команда с 0 игроками.

И ожидаемый результат изменится на:

Team Name         PlayerCount
Miami Heat        2
New York Knicks   1
Toronto Rapters   0

, так как один из игроков Miami Heat еще не проходил медосмотр.

Если я добавлю

LEFT JOIN MEDICALTESTS m ON p.PlayerId = m.PlayerId
WHERE m.PassedMedical = 1

Из вышеприведенного утверждения я теряю все строки "0"?

Спасибо,
Джастин

Ответы [ 4 ]

2 голосов
/ 23 августа 2010
LEFT JOIN MEDICALTESTS m ON p.PlayerId = m.PlayerId
WHERE m.PassedMedical = 1

Это противоречиво.Вы говорите, что это левое соединение, поэтому запись MEDICALTESTS не должна существовать, но затем говорите, что запись должна фактически существовать и иметь 1 как PassedMedical.Таким образом, ваше левое соединение фактически становится внутренним соединением, а также, поскольку у вас должна быть строка MEDICALTESTS, у вас также должна быть строка PLAYERS, чтобы она также стала внутренним соединением.

Попробуйте вместо этого:

INNER JOIN MEDICALTESTS m ON p.PlayerId = m.PlayerId and m.PassedMedical = 1

Не уверен, как SQL-сервер интерпретирует FROM foo LEFT JOIN bar INNER JOIN baz ... Вы хотите, чтобы он интерпретировал это как FROM foo LEFT JOIN (bar INNER JOIN baz).Если это не сработает, используйте вместо этого выборку;не присоединяйтесь, просто добавьте:

WHERE p.PlayerId IS NULL or (select PassedMedical from MEDICALTESTS m where m.PlayerId=p.PlayerID) = 1 

Надеюсь, это поможет, несмотря на мое незнакомство с SQL Server.

1 голос
/ 23 августа 2010

Прочтите это, чтобы понять проблему, с которой вы столкнулись: http://wiki.lessthandot.com/index.php/WHERE_conditions_on_a_LEFT_JOIN

По сути, помещая условие в класс where, вы конвертируете левое соединение во внутреннее соединение. Попробуйте вместо этого:

LEFT JOIN MEDICALTESTS m ON p.PlayerId = m.PlayerId 
and m.PassedMedical = 1 
1 голос
/ 23 августа 2010

Почему бы не сделать это как вычисляемый столбец?

SELECT
    t.teamid, 
    t.teamname,
    (SELECT COUNT(*) FROM MEDICALTESTS m WHERE p.PlayerId = m.PlayerId and m.PassedMedical = 1 ) AS PassedMedicalCount
1 голос
/ 23 августа 2010

Простите, если я неправильно понял вопрос, но я не вижу необходимости левого соединения на столе игроков.Нам нужно только количество игроков.Почему не что-то вроде:

SELECT t.teamid,
          t.teamname, 
          (SELECT COUNT(*) FROM players inner join medicaltests on players.playerid = medicaltests.playerid where players.teamid = t.teamid and medicaltests.passedmedical = 1) AS playercount,
          t.rosterspots
     FROM TEAMS t
 GROUP BY t.teamid, t.teamname, t.rosterspots
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...