英文:
How to get null for rows where data doesn't exist in Postgres while performing joins
问题
I have 2 tables: Items and Rates. Items and Rates are linked using a FK on Rates. If the rate of the item is not present for the day then it is not stored. So for item 5 if no rate is present on 1st January there won't be a record for item 5.
我有2个表:Items(项目)和Rates(费率)。Items和Rates通过Rates上的外键连接在一起。如果项目的费率在某天不存在,那么不会存储记录。因此,对于项目5,如果在1月1日没有费率记录,那么就不会有项目5的记录。
I want item 5 rate as null.
我想要项目5的费率为空。
How can I proceed?
我应该如何继续?
Left Join is not working; depending on the data, sometimes I get the date as null, sometimes everything except the item PK is null.
左连接(Left Join)不起作用;根据数据的不同,有时我会得到日期为null,有时除了项目主键之外的一切都为null。
英文:
I have 2 tables: Items and Rates. Items and Rates are linked using a FK on Rates. If the rate of the item is not present for the day then it is not stored. So for item 5 if no rate is present on 1st January there won't be a record for item 5.
I want item 5 rate as null.
How can I proceed?
Left Join is not working; depending on the data, sometimes I get the date as null, sometimes everything except the item PK is null.
答案1
得分: 2
左连接是正确的方法,但你需要一个包含你想要的所有行的表,而你现在没有这个表。但你可以通过对你的表进行明确的交叉连接来创建它。
select to_char(x.date, 'DD-MON-YYYY'), x.pk, rates.rate
from (
select distinct date, pk
from items, rates
) x
left outer join rates
on x.pk = rates.item
and x.date = rates.date
order by x.date, x.pk
产生以下结果:
to_char | pk | rate |
---|---|---|
01-JAN-2023 | 1 | 10 |
01-JAN-2023 | 2 | 12 |
01-JAN-2023 | 3 | |
01-JAN-2023 | 4 | |
01-JAN-2023 | 5 | |
02-JAN-2023 | 1 | 11 |
02-JAN-2023 | 2 | |
02-JAN-2023 | 3 | 13 |
02-JAN-2023 | 4 | 14 |
02-JAN-2023 | 5 |
使用以下设置:
create table items(
pk integer,
name varchar(50)
);
create table rates(
item integer,
date date,
rate integer
);
insert into items (pk, name) values
(1, 'A'),
(2, 'B'),
(3, 'C'),
(4, 'D'),
(5, 'E');
insert into rates (item, date, rate) values
(1, '1-Jan-2023', 10),
(1, '2-Jan-2023', 11),
(2, '1-Jan-2023', 12),
(3, '2-Jan-2023', 13),
(4, '2-Jan-2023', 14);
英文:
A left join is the right approach, but you need a table that contains all the rows that you want in the result, and you don't have that.
But you can create it with a distinct cross join of your tables.
select to_char(x.date, 'DD-MON-YYYY'), x.pk, rates.rate
from (
select distinct date, pk
from items, rates
) x
left outer join rates
on x.pk = rates.item
and x.date = rates.date
order by x.date, x.pk
produces
to_char | pk | rate |
---|---|---|
01-JAN-2023 | 1 | 10 |
01-JAN-2023 | 2 | 12 |
01-JAN-2023 | 3 | |
01-JAN-2023 | 4 | |
01-JAN-2023 | 5 | |
02-JAN-2023 | 1 | 11 |
02-JAN-2023 | 2 | |
02-JAN-2023 | 3 | 13 |
02-JAN-2023 | 4 | 14 |
02-JAN-2023 | 5 |
With the following setup:
create table items(
pk integer,
name varchar(50)
);
create table rates(
item integer,
date date,
rate integer
);
insert into items (pk, name) values
(1, 'A'),
(2, 'B'),
(3, 'C'),
(4, 'D'),
(5, 'E');
insert into rates (item, date, rate) values
(1, '1-Jan-2023', 10),
(1, '2-Jan-2023', 11),
(2, '1-Jan-2023', 12),
(3, '2-Jan-2023', 13),
(4, '2-Jan-2023', 14);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论