表 A:用戶擁有的編碼記錄 `(id, no, name, status)`。
表 C:標準編碼庫 `(no)`。
需求:找出每個用戶缺少的編碼,並以 `status='add'` 批量插入表 A。
表 A:
(1, 'A', '張三', 'add')
(1, 'B', '張三', 'del') -- 已刪除,視為不擁有
(2, 'A', '李四', 'add')
(3, 'B', '王五', 'update')
表 C:
('A'), ('B'), ('C')
預期結果:
張三 缺 C → 插入 (1, 'C', '張三', 'add')
李四 缺 B、C → 插入 (2, 'B', '李四', 'add'), (2, 'C', '李四', 'add')
王五 缺 A、C → 插入 (3, 'A', '王五', 'add'), (3, 'C', '王五', 'add')
INSERT INTO A (id, no, name, status)
SELECT u.id, c.no, u.name, 'add'
FROM (
SELECT DISTINCT id, name
FROM A
WHERE status <> 'del'
) u
CROSS JOIN C c
WHERE NOT EXISTS (
SELECT 1
FROM A a2
WHERE a2.id = u.id
AND a2.no = c.no
AND a2.status <> 'del'
);
-- MySQL: 使用 NOT IN (需注意 NULL 值陷阱,建議用 NOT EXISTS)
INSERT INTO A (id, no, name, status)
SELECT u.id, c.no, u.name, 'add'
FROM (SELECT DISTINCT id, name FROM A WHERE status <> 'del') u
CROSS JOIN C c
WHERE (u.id, c.no) NOT IN (SELECT id, no FROM A WHERE status <> 'del');
-- SQL Server: 使用 MERGE (2008+) 實現 Upsert
MERGE INTO A AS target
USING (
SELECT u.id, c.no, u.name
FROM (SELECT DISTINCT id, name FROM A WHERE status <> 'del') u
CROSS JOIN C c
) AS source
ON target.id = source.id AND target.no = source.no
WHEN NOT MATCHED THEN
INSERT (id, no, name, status) VALUES (source.id, source.no, source.name, 'add');
insert into ma(id, fe, vname, 狀態字段)
values(
SELECT id, vname, fe, 'add'
FROM (
SELECT c.*, c.vname + ',' + c.fe as kid
FROM (
SELECT * FROM (
SELECT DISTINCT id, vname FROM ma
) a, (SELECT fe FROM mb) b
) c
) D
WHERE kid NOT IN (SELECT VNAME + ',' + FE FROM ma WHERE 狀態字段 <> 'del')
)