[英]Getting all rows of one table, and matching rows from another table where entries may not exist in SQL
so what I have is a database where records have an ID
and a YEAR
associated with them. 因此,我所拥有的是一个数据库,其中的记录具有ID
和与之关联的YEAR
。 Each YEAR
will only have one record for each ID
, but every ID
doesn't necessarily exist in a given YEAR
. 每个YEAR
的每个ID
只会有一个记录,但是每个ID
在给定的YEAR
不一定存在。 So, what I'm trying to do is get a list of every record from my table for the 2018 YEAR
, and get a certain value from the three previous years. 所以,我想要做的是从我的表2018年获得每一条记录的清单YEAR
,并得到前三年一定的价值。 My issue is that if a record from 2018 didn't exist in 2017, I won't get it at all. 我的问题是,如果2017年的记录在2017年不存在,我将一无所获。 I want to just fill in NULL fields with a 0 or something, but still keep that ID
. 我只想用0或其他值填充NULL字段,但仍保留该ID
。
What I have so far (which obviously doesn't work) is: 我到目前为止(显然是行不通的)是:
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;
I tried doing a join like: 我试着做像这样的联接:
SELECT a.ID, b.VAL FROM table as a LEFT JOIN table as b on a.ID = b.ID WHERE...
but that still showed the same issue. 但这仍然显示相同的问题。 I should also mention I'm doing this in MS ACCESS. 我还应该提到我正在MS ACCESS中进行此操作。
Hopefully I understand the data structure you're describing. 希望我能理解您所描述的数据结构。 The variable table below is my interpretation. 下面的变量表是我的解释。 If this is correct then the code below it should give you what you're looking for. 如果这是正确的,那么下面的代码将为您提供所需的内容。
The key difference is the 'AND' in the 'ON' clause vs in the 'WHERE'. 关键区别在于“ ON”子句中的“ AND”与“ WHERE”中的“ AND”。 If you put the criteria in the 'WHERE' then you're essentially turning your LEFT OUTER JOIN into an INNER JOIN by asserting that the criteria must be true after the join is completed. 如果将条件放在“ WHERE”中,则实际上是在断言连接完成后,条件必须为true,从而将您的LEFT OUTER JOIN转换为INNER JOIN。 Whereas in the 'ON' you're telling SQL that it must be true in order to do the join itself. 而在“ ON”中,您告诉SQL它必须为true才能进行联接本身。
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
I would just use conditional aggregation: 我只会使用条件聚合:
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;
If you only want rows where 2018
is present, then include: 如果只希望存在2018
行,则包括:
HAVING MAX(a.YEAR) = 2018
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.