如何根据条件复制行
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 =1234
和 ACCN=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
我有以下表格:
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 =1234
和 ACCN=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