如何在执行Postgres连接时获取不存在数据的行中获取null。

huangapple go评论54阅读模式
英文:

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。

英文:

如何在执行Postgres连接时获取不存在数据的行中获取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);

在DB Fiddle上查看

英文:

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);

View on DB Fiddle

huangapple
  • 本文由 发表于 2023年2月24日 17:26:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75554781.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定