Join two tables on multiple columns with case that return not fully matched raws with replacement of not matched value

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

Join two tables on multiple columns with case that return not fully matched raws with replacement of not matched value

问题

Here's the translation of the provided text:

我有表A

raw_number ars bill codt c4
1 900 603121 123
2 900 603121 YPR-003 234
3 900 603121 Psp-123 345
4 900 603121 456
5 900 603121 567

和表B

raw_number ars bill codt s4
1 900 603121 Psp-123 asd
2 900 603121 zxc
3 900 455000 F

我正在将表A与表B连接,连接条件是“ars”,“bill”,“codt”列。

我的目标是获得以下结果:

ars bill codt c4 s4
900 603121 123 zxc
900 603121 234 zxc
900 603121 Psp-123 345 asd
900 603121 456 zxc
900 603121 567 zxc

“raw_number”列用于解释:对于来自表A的raw number 3,匹配必须是来自表B的raw 1,因为它完全匹配,但来自A的raw number 2必须与来自B的raw 2匹配。

原始查询更复杂,因为表A和B是来自其他连接的结果。

更新后的查询如下:

  1. SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  2. FROM A a LEFT JOIN B b ON a.ars = b.ars
  3. AND a.bill = b.bill
  4. AND a.codt IS DISTINCT FROM b.codt
  5. UNION
  6. SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  7. FROM A a LEFT JOIN B b ON a.ars = b.ars AND a.bill = b.bill
  8. AND a.codt = b.codt

看起来这是我想要的,但我不确定,因为我的原始查询周围还有其他联合操作,看起来很庞大,有1200多行。也许有人有其他想法?

英文:

I have table A

raw_number ars bill codt c4
1 900 603121 123
2 900 603121 YPR-003 234
3 900 603121 Psp-123 345
4 900 603121 456
5 900 603121 567

and table B

raw_number ars bill codt s4
1 900 603121 Psp-123 asd
2 900 603121 zxc
3 900 455000 F

Im joining table A with table B on "ars", "bill", "codt" columns.

My point is getting this result:

ars bill codt c4 s4
900 603121 123 zxc
900 603121 234 zxc
900 603121 Psp-123 345 asd
900 603121 456 zxc
900 603121 567 zxc

columns "raw_number" added for explanations : for raw number 3 from table A match must be raw 1 from table B, cos its fully matched, but raw number 2 from A must match with raw 2 from B

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

is not working for me cos it returns null values from table B for raw number 3 A table
INNER JOIN is not a point too cos remove this raw

original query is more complicated because tables A and B is a results from another joins

UPDATE:
After an NBK answer i try this

  1. SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  2. FROM A a LEFT JOIN B b ON a.ars = b.ars
  3. AND a.bill = b.bill
  4. AND a.codt IS DISTINCT FROM b.codt
  5. UNION
  6. SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  7. FROM A a LEFT JOIN B b ON a.ars = b.ars AND a.bill = b.bill
  8. AND a.codt = b.codt

it looks like i want but im not sure because my original query with this have another unions around and looks monstrous.. 1200+ raws
Maybe someone have another idea?

答案1

得分: 1

下面是您要翻译的内容:

  1. if codt codt is an emtypoyt string = works, you neeed only take care of the NULL if no match is found
  2. CREATE TABLE A (
  3. "raw_number" INTEGER,
  4. "ars" INTEGER,
  5. "bill" INTEGER,
  6. "codt" VARCHAR(7),
  7. "c4" INTEGER
  8. );
  9. INSERT INTO A
  10. ("raw_number", "ars", "bill", "codt", "c4")
  11. VALUES
  12. ('1', '900', '603121','', '123'),
  13. ('2', '900', '603121', 'YPR-003', '234'),
  14. ('3', '900', '603121', 'Psp-123', '345'),
  15. ('4', '900', '603121', '', '456'),
  16. ('5', '900', '603121', '', '567');
  1. CREATE TABLE B (
  2. "raw_number" INTEGER,
  3. "ars" INTEGER,
  4. "bill" INTEGER,
  5. "codt" VARCHAR(7),
  6. "s4" VARCHAR(3)
  7. );
  8. INSERT INTO B
  9. ("raw_number", "ars", "bill", "codt", "s4")
  10. VALUES
  11. ('1', '900', '603121', 'Psp-123', 'asd'),
  12. ('2', '900', '603121', '', 'zxc'),
  13. ('3', '900', '455000', '', 'F');
  1. 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 = ''))
  2. FROM A a
  3. LEFT JOIN B b ON
  4. a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt

fiddle

  1. 这是您提供的SQL代码的翻译部分。
  2. <details>
  3. <summary>英文:</summary>
  4. if codt codt is an emtypoyt string = works, you neeed only take care of the NULL if no match is found

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

  1. &gt; ``` status
  2. &gt; CREATE TABLE
  3. &gt; ```
  4. &gt; ``` status
  5. &gt; INSERT 0 5
  6. &gt; ```

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

  1. &gt; ``` status
  2. &gt; CREATE TABLE
  3. &gt; ```
  4. &gt; ``` status
  5. &gt; INSERT 0 3
  6. &gt; ```

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

  1. | ars | bill | codt | c4 | coalesce |
  2. |----:|-----:|:-----|---:|:---------|
  3. | 900 | 603121 | | 123 | zxc |
  4. | 900 | 603121 | | 456 | zxc |
  5. | 900 | 603121 | | 567 | zxc |
  6. | 900 | 603121 | Psp-123 | 345 | asd |
  7. | 900 | 603121 | YPR-003 | 234 | zxc |
  8. &gt; ``` status
  9. &gt; SELECT 5
  10. &gt; ```
  11. [fiddle](https://dbfiddle.uk/P4nSx_yC)
  12. t
  13. </details>
  14. # 答案2
  15. **得分**: 1
  16. This query will return the data you requested but *s4* is missing.
  17. 这个查询将返回您请求的数据,但缺少 *s4*。
  18. SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  19. FROM A a
  20. LEFT JOIN B b ON a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt and a.codt &lt;&gt; &#39;&#39;
  21. order by ars, bill, c4
  22. 这将返回:
  23. ars | bill | codt | c4 | s4
  24. ---|------|-----|-------|----
  25. 900 | 603121 | null | 123 | null
  26. 900 | 603121 | null | 234 | null
  27. 900 | 603121 | Psp-123 | 345 | asd
  28. 900 | 603121 | null | 456 | null
  29. 900 | 603121 | null | 567 | null
  30. Then will get *s4* from *table B* when s4 is null using `inner join` :
  31. 然后,当 s4 null 时,将从 *表 B* 获取 *s4* 使用 `inner join`
  32. 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
  33. from B b
  34. inner join (
  35. SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  36. FROM A a
  37. LEFT JOIN B b ON a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt and a.codt &lt;&gt; &#39;&#39;
  38. ) as s on s.ars = b.ars and s.bill = b.bill
  39. where b.codt = &#39;&#39;
  40. order by ars, bill, c4
  41. Result :
  42. ars | bill | codt | c4 | s4
  43. ---|------|-----|------|---
  44. 900 | 603121 | null | 123 | zxc
  45. 900 | 603121 | null | 234 | zxc
  46. 900 | 603121 | Psp-123 | 345 | asd
  47. 900 | 603121 | null | 456 | zxc
  48. 900 | 603121 | null | 567 | zxc
  49. [Demo here][1]
  50. [1]: https://dbfiddle.uk/fz7Ox1cN
  51. <details>
  52. <summary>英文:</summary>
  53. This query will return the data you requested but *s4* is missing.
  54. SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  55. FROM A a
  56. LEFT JOIN B b ON a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt and a.codt &lt;&gt; &#39;&#39;
  57. order by ars, bill, c4
  58. This will return :
  59. ars |bill |codt |c4 |s4
  60. ---|------|-----|-------|----
  61. 900 |603121| null |123| null
  62. 900 |603121| null |234| null
  63. 900 |603121| Psp-123 |345| asd
  64. 900 |603121| null |456| null
  65. 900 |603121| null |567| null
  66. Then will get *s4* from *table B* when s4 is null using `inner join` :
  67. 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
  68. from B b
  69. inner join (
  70. SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  71. FROM A a
  72. LEFT JOIN B b ON a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt and a.codt &lt;&gt; &#39;&#39;
  73. ) as s on s.ars = b.ars and s.bill = b.bill
  74. where b.codt = &#39;&#39;
  75. order by ars, bill, c4
  76. Result :
  77. ars |bill| codt| c4| s4
  78. ---|------|-----|------|---
  79. 900 |603121| null| 123| zxc
  80. 900 |603121| null| 234| zxc
  81. 900 |603121| Psp-123| 345| asd
  82. 900 |603121| null| 456| zxc
  83. 900 |603121| null| 567| zxc
  84. [Demo here][1]
  85. [1]: https://dbfiddle.uk/fz7Ox1cN
  86. </details>
  87. # 答案3
  88. **得分**: 1
  89. 以下是翻译好的部分:
  90. "根据我理解,您想将存在于 A 中但不存在于 B 中的 `codt` 值与 B 中的空字符串 `codt` 匹配,您可以在连接之前检查 `B` 中 `codt` 的存在性,如下所示:
  91. ```sql
  92. SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  93. FROM
  94. (
  95. SELECT ars, bill,
  96. CASE
  97. WHEN
  98. EXISTS(SELECT 1 FROM B d WHERE d.ars=t.ars AND d.bill=t.bill AND d.codt= t.codt) THEN codt
  99. ELSE ''
  100. END AS codt, c4
  101. FROM A t
  102. ) a
  103. LEFT JOIN B b ON
  104. a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt
  105. ORDER BY c4

查看示例

英文:

As I understood, you want to match the codt value that exists in A but not in B with the empty string codt from B, you could check the existence of codt in B before joining as the following:

  1. SELECT a.ars, a.bill, b.codt, a.c4, b.s4
  2. FROM
  3. (
  4. select ars, bill,
  5. case
  6. when
  7. exists(select 1 from B d where d.ars=t.ars and d.bill=t.bill and d.codt= t.codt) then codt
  8. else &#39;&#39;
  9. end as codt, c4
  10. from A t
  11. ) a
  12. LEFT JOIN B b ON
  13. a.ars = b.ars AND a.bill = b.bill AND a.codt = b.codt
  14. ORDER BY c4

See demo

huangapple
  • 本文由 发表于 2023年5月6日 18:38:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76188427.html
匿名

发表评论

匿名网友

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

确定