Получение всех строк одной таблицы и сопоставление строк из другой таблицы, где записи могут не существовать в SQL - PullRequest
0 голосов
/ 06 июня 2018

, так что у меня есть база данных, в которой записи имеют ID и YEAR, связанные с ними.Каждый YEAR будет иметь только одну запись для каждого ID, но каждый ID не обязательно существует в данном YEAR.Итак, что я пытаюсь сделать, это получить список каждой записи из моей таблицы на 2018 YEAR и получить определенное значение за три предыдущих года.Моя проблема в том, что если в 2017 году не будет записи 2018 года, я ее вообще не получу.Я хочу просто заполнить NULL-поля 0 или чем-то еще, но при этом оставить это ID.

То, что у меня есть (что, очевидно, не работает):

SELECT a.ID, b.VAL, c.VAL, d.VAL
FROM table as a, table as b, table as c, table as d
WHERE a.YEAR = 2018 AND b.YEAR = 2017 AND c.YEAR = 2016 AND d.YEAR = 2015 AND a.ID = b.ID AND b.ID = c.ID AND c.ID = d.ID;

Я пытался сделать соединение как:

SELECT a.ID, b.VAL FROM table as a LEFT JOIN table as b on a.ID = b.ID WHERE...

, но это все еще показывало ту же проблему.Я должен также упомянуть, что я делаю это в MS ACCESS.

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Я бы просто использовал условное агрегирование:

SELECT a.ID,
       SUM(IIF(a.YEAR = 2018, a.VAL, 0)) as val_2018,
       SUM(IIF(a.YEAR = 2017, a.VAL, 0)) as val_2017,
       SUM(IIF(a.YEAR = 2016, a.VAL, 0)) as val_2016,
       SUM(IIF(a.YEAR = 2015, a.VAL, 0)) as val_2015
FROM table as a
WHERE a.YEAR IN (2015, 2016, 2017, 2018)
GROUP BY a.id;

Если вам нужны только строки, в которых присутствует 2018, включите:

HAVING MAX(a.YEAR) = 2018
0 голосов
/ 06 июня 2018

Надеюсь, я понимаю структуру данных, которую вы описываете.Таблица переменных ниже - моя интерпретация.Если это правильно, то код ниже должен дать вам то, что вы ищете.

Ключевым отличием является «И» в предложении «ВКЛ» против «ГДЕ».Если вы поместите критерии в поле «ГДЕ», то вы по сути превращаете свое ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ в ВНУТРЕННЕЕ СОЕДИНЕНИЕ, утверждая, что критерии должны быть истинными после завершения соединения.В то время как в «ON» вы говорите SQL, что оно должно быть истинным, чтобы выполнить само соединение.

declare @tbl table ([year] int, [id] int, [someval] varchar(50))
insert into @tbl values (2018, 1, 'one')
insert into @tbl values (2018, 2, 'two')
insert into @tbl values (2017, 1, 'three')
insert into @tbl values (2016, 1, 'four')
insert into @tbl values (2015, 1, 'five')
insert into @tbl values (2015, 2, 'six')
insert into @tbl values (2015, 3, 'seven')

;with t2018 as(select * from @tbl where [year]=2018)
,t2017 as(select * from @tbl where [year]=2017)
,t2016 as(select * from @tbl where [year]=2016)
,t2015 as(select * from @tbl where [year]=2015)
select isnull(t2018.id,isnull(t2017.id,isnull(t2016.id,t2015.id))) as id,
     t2018.someval as [2018SomeVal],
     t2017.someval as [2017SomeVal], 
     t2016.someval as [2016SomeVal], 
     t2015.someval as [2015SomeVal]
from t2018
    full outer join t2017 on t2017.id = t2018.id
    full outer join t2016 on t2016.id = t2018.id
    full outer join t2015 on t2015.id = t2018.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...