如何根据条件复制行

How to duplicate rows based on conditions

我有以下表格:

create table Contacts (key1 int, Accn varchar (20))
INSERT INTO Contacts 
select 1234,'ABCD' UNION
select 1234,'EFG' UNION
select 1234,'GAB' UNION
select 1234,'PBC' UNION
select 89023,'MONQ'  
   

CREATE TABLE SCANDOCS (Accn varchar (20), FileDesc varchar (50),BReg  varchar (50))
select 'ABCD','100_MP','813' union
select 'ABCD','200_KA','843' union
select 'EFG','100_MP','3209' union
select 'GAB','800_JLZG','2357' union
select 'MONQ','700_NMO','94266' 
 

我需要找到 Key1 并检查其在 Scandocs 中的 filedesc 列中的 accn 是否具有值“100_MP”或“200_KA”。在示例中,它存在于 Key1 =1234ACCN=ABCD,EFG 中。一旦我找到一个特定的键,我需要在 Scandocs 中插入一行,用于该键下没有这些 filedesc 的所有其他 accn。

此外,如果某个键下的 accn 具有这些值之一但具有不同的 BReg,那么同一键下的另一个 acc 具有相同的 fildesc 我还需要将该行插入到 scandocs 中,而 accn 不具有相同的 filedesc 和 Breg.

结果应该是

accn      | filedesc  | Breg
ABCD      | 100_MP    |813
ABCD      | 200_KA    |843
ABCD      | 100_MP    |3209
EFG       | 100_MP    |813
EFG       | 100_MP    |3209
EFG       | 200_KA    |843
GAB       |800_JLZG   |2357
GAB       | 100_MP    |813
GAB       | 200_KA    |843
GAB       | 100_MP    |3209
MONQ      |700_NMO    |94266

MONQ acc 在 key1=89023 下,key1 下没有 acc 的 filedesc 值为 100_mp 或 200_KA 所以我们不需要复制 100 或 200 的行,因为它们对于那个键 1 不存在。

谢谢

如果你生成了所有应该存在的东西。
然后你可以将它与已经存在的进行比较。

此处的解决方案插入了 CTE_ALL_ACC_FD 中与 SCANDOCS 中已有内容不匹配的所有内容。

WITH CTE_ACCOUNTS AS (
  SELECT c.accn, c.key1
  FROM Contacts c
  INNER JOIN SCANDOCS d 
    ON d.accn = c.accn
  WHERE c.key1 = 1234
  GROUP BY c.accn, c.key1
)
, CTE_FILEDESCS AS
(
  SELECT DISTINCT filedesc, breg
  FROM SCANDOCS
  WHERE accn IN (select accn from CTE_ACCOUNTS)
    AND filedesc IN ('100_MP','200_KA')
)
, CTE_ALL_ACC_FD AS (
  SELECT DISTINCT accn, filedesc, breg
  FROM CTE_ACCOUNTS a
  CROSS JOIN CTE_FILEDESCS fd
)
INSERT INTO SCANDOCS (
 accn, 
 filedesc, 
 breg
)
SELECT 
 afd.accn, 
 afd.filedesc, 
 afd.breg
FROM CTE_ALL_ACC_FD afd
LEFT JOIN SCANDOCS sdoc 
  ON sdoc.accn = afd.accn
 AND sdoc.filedesc = afd.filedesc
 AND sdoc.breg = afd.breg
WHERE sdoc.filedesc IS NULL;
6 rows affected
SELECT *
FROM SCANDOCS
ORDER BY accn, filedesc
accn | filedesc | breg 
:--- | :------- | :----
ABCD | 100_MP   | 3209 
ABCD | 100_MP   | 813  
ABCD | 200_KA   | 843  
EFG  | 100_MP   | 3209 
EFG  | 100_MP   | 813  
EFG  | 200_KA   | 843  
GAB  | 100_MP   | 3209 
GAB  | 100_MP   | 813  
GAB  | 200_KA   | 843  
GAB  | 800_JLZG | 2357 
MONQ | 700_NMO  | 94266

db<>fiddle here