postgresql 连接两个表的多个列,case返回不完全匹配的raws,替换不匹配的值

hec6srdp  于 2023-05-17  发布在  PostgreSQL
关注(0)|答案(3)|浏览(108)

我订了A桌
| 原始数|阿尔斯|帐单|科特|碳四|
| --------------|--------------|--------------|--------------|--------------|
| 1|九百|603121||一百二十三|
| 二|九百|603121|公司简介|二百三十四|
| 三|九百|603121| PSP-123|三百四十五|
| 四个|九百|603121||四五六|
| 五|九百|603121||五六七|
和表B
| 原始数|阿尔斯|帐单|科特|s4|
| --------------|--------------|--------------|--------------|--------------|
| 1|九百|603121| PSP-123| ASD|
| 二|九百|603121||公司简介|
| 三|九百|四十五万五千||F级|
我正在把A桌和B桌的“ars”、“bill”、“codt”三栏连接起来。
我的观点是得到这个结果:
| 阿尔斯|帐单|科特|碳四|s4|
| --------------|--------------|--------------|--------------|--------------|
| 九百|603121||一百二十三|公司简介|
| 九百|603121||二百三十四|公司简介|
| 九百|603121| PSP-123|三百四十五|ASD|
| 九百|603121||四五六|公司简介|
| 九百|603121||五六七|公司简介|
为解释添加了列“raw_number”:对于来自表A的原始编号3,匹配必须是来自表B的原始编号1,因为其完全匹配,但是来自A的原始编号2必须与来自B的原始编号2匹配

SELECT a.ars, a.bill, b.codt, a.c4, b.s4
FROM A a
LEFT JOIN B b ON
a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt

对我不起作用,因为它从表B返回空值,用于原始编号3表A
INNER JOIN不是一个点太COS删除此原始
原始查询更复杂,因为表A和B是另一个连接的结果
更新:在NBK回答后,我尝试了这个

SELECT a.ars, a.bill, b.codt, a.c4, b.s4 
FROM A a LEFT JOIN B b ON a.ars = b.ars 
AND a.bill = b.bill 
AND a.codt IS DISTINCT FROM b.codt 
UNION  
SELECT a.ars, a.bill, b.codt, a.c4, b.s4 
FROM A a LEFT JOIN B b ON a.ars = b.ars AND a.bill = b.bill 
AND a.codt = b.codt

它看起来像我想要的,但我不确定,因为我原来的查询与此有另一个工会周围,看起来可怕。1200+ raws也许有人有另一个想法?

uqdfh47h

uqdfh47h1#

此查询将返回您请求的数据,但 s4 丢失。

SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  FROM A a
  LEFT JOIN B b ON a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt and a.codt <> ''
  order by ars, bill, c4

这将返回:
| 阿尔斯|帐单|科特|碳四|s4|
| --------------|--------------|--------------|--------------|--------------|
| 九百|603121|零|一百二十三|零|
| 九百|603121|零|二百三十四|零|
| 九百|603121| PSP-123|三百四十五|ASD|
| 九百|603121|零|四五六|零|
| 九百|603121|零|五六七|零|
然后,当s4为空时,将使用inner jointable B 获取 s4

select DISTINCT s.ars, s.bill, s.codt, s.c4, case when s.s4 is not null then s.s4 else b.s4 end as s4 
from B b
inner join (
  SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  FROM A a
  LEFT JOIN B b ON a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt and a.codt <> ''
) as s on s.ars = b.ars and s.bill = b.bill
where b.codt = ''
order by ars, bill, c4

结果:
| 阿尔斯|帐单|科特|碳四|s4|
| --------------|--------------|--------------|--------------|--------------|
| 九百|603121|零|一百二十三|公司简介|
| 九百|603121|零|二百三十四|公司简介|
| 九百|603121| PSP-123|三百四十五|ASD|
| 九百|603121|零|四五六|公司简介|
| 九百|603121|零|五六七|公司简介|
Demo here

t3psigkw

t3psigkw2#

如果codt codt是一个emtypoyt string = works,则只需要在没有找到匹配的情况下处理NULL

CREATE TABLE A (
  "raw_number" INTEGER,
  "ars" INTEGER,
  "bill" INTEGER,
  "codt" VARCHAR(7),
  "c4" INTEGER
);

INSERT INTO A
  ("raw_number", "ars", "bill", "codt", "c4")
VALUES
  ('1', '900', '603121','', '123'),
  ('2', '900', '603121', 'YPR-003', '234'),
  ('3', '900', '603121', 'Psp-123', '345'),
  ('4', '900', '603121', '', '456'),
  ('5', '900', '603121', '', '567');
CREATE TABLE
INSERT 0 5
CREATE TABLE B (
  "raw_number" INTEGER,
  "ars" INTEGER,
  "bill" INTEGER,
  "codt" VARCHAR(7),
  "s4" VARCHAR(3)
);

INSERT INTO B
  ("raw_number", "ars", "bill", "codt", "s4")
VALUES
  ('1', '900', '603121', 'Psp-123', 'asd'),
  ('2', '900', '603121', '', 'zxc'),
  ('3', '900', '455000', '', 'F');
CREATE TABLE
INSERT 0 3
SELECT a.ars, a.bill, a.codt, a.c4, COALESCE(b.s4,(SELECT s4 FROM B b1 WHERE a.ars = b1.ars AND a.bill = b1.bill and codt = ''))
FROM A a
LEFT JOIN B b ON
a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt
阿尔斯帐单科特碳四聚结
九百603121一百二十三公司简介
九百603121四五六公司简介
九百603121五六七公司简介
九百603121PSP-123三百四十五ASD
九百603121公司简介二百三十四公司简介
SELECT 5

fiddle t

koaltpgm

koaltpgm3#

正如我所理解的,你想将存在于A中但不存在于B中的codt值与来自B的空字符串codt匹配,你可以在加入之前检查codt在B中的存在性,如下所示:

SELECT a.ars, a.bill, b.codt, a.c4, b.s4
FROM 
  (
    select ars, bill, 
      case 
        when 
         exists(select 1 from B d where d.ars=t.ars and d.bill=t.bill and d.codt= t.codt) then codt 
        else '' 
      end as codt, c4
   from A t
  ) a
LEFT JOIN B b ON
a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt
ORDER BY c4

See demo

相关问题