Выражение case не возвращает значение else в запросе Postgres

Я создаю SQL-запрос с большим количеством вложенных запросов и пытаюсь использовать выражение CASE, но оно ведет себя странно.

Это мой запрос на данный момент:

select t.fpl_id, t.team_name,
sum(pf.points)as gwpts,
(
    select sum(transfers_malus)
    from gameweeks
    where gameweeks.team_id = t.id and gameweeks.number = g.number
)as malus,
(
    select sum(points)
    from player_fixtures as pfix
    where gw_number = g.number and pfix.player_id = CASE WHEN minutes_played > 0 THEN g.captain_id ELSE g.vice_captain_id END
)
as cpts,
 (
    select max(web_name)
    from players
    join player_fixtures on players.id = player_fixtures.player_id and gw_number = g.number
    where players.id = CASE WHEN player_fixtures.minutes_played > 0 THEN g.captain_id ELSE g.vice_captain_id END
) as captain_name,
array_agg(p.id) as lineup
from teams as t
join gameweeks as g on t.id  = g.team_id
join gameweeks_players as gp on gp.gameweek_id = g.id
join players as p on gp.player_id = p.id
join player_fixtures as pf on p.id = pf.player_id  and pf.gw_number = g.number
where t.id = 1
group by t.id, g.id
order by g.number asc

Проблема в том, что у меня проблема в том, что я делаю заявление случая, чтобы узнать, не играл ли кто-либо из игроков (капитан) на основании "minutes_played":

(select sum(points)
    from player_fixtures as pfix
    where gw_number = g.number and pfix.player_id = CASE WHEN minutes_played > 0 THEN g.captain_id ELSE g.vice_captain_id END
) as cpts

а также

 (
    select max(web_name)
    from players
    join player_fixtures on players.id = player_fixtures.player_id and gw_number = g.number
    where players.id = CASE WHEN player_fixtures.minutes_played > 0 THEN g.captain_id ELSE g.vice_captain_id END
) as captain_name,

Когда minutes_played действительно больше 0, все работает нормально. Однако, когда он равен 0, он просто ничего не "возвращает", и я получаю NULL взамен в моей строке. minutes_played - целое число, и когда я пытаюсь с помощью следующего скрипта на player_fixtures, где minutes_played = 0, моя оценка> работает, и я получаю правильное "ПЛОХО".

DO LANGUAGE plpgsql $$
    BEGIN
        IF (select minutes_played from player_fixtures where gw_number = 19 and player_id = 266 ) > 0 THEN 
            RAISE NOTICE 'GOOD';
        ELSE
            RAISE NOTICE 'BAD';
        END IF;
    END;
$$;

Я довольно новичок во всей этой DB, так что, вероятно, я делаю ошибку новичка, но я пытался в течение последних 6 часов без какой-либо удачи. Может ли кто-нибудь указать мне правильное направление?

1 ответ

Проблема в том, что когда нет подходящих строк, sum() возвращает ноль, и никакое сравнение с нулем никогда не бывает истинным.

Вместо этого используйте exists(), например:

where exists(select * from player_fixtures
    where gw_number = 19
    and player_id = 266 
    and minutes_played > 0)

или вы можете использовать if exists(...) then в хранимой процедуре.

Другие вопросы по тегам