问题所在
我需要查找并删除两个表中所有相同的行,这些表的模式可能经常更改.在本例中,EQUAL表示各行中的所有值彼此相等,例如:
ID | Message | Date | = | ID | Message | Date |
---|---|---|---|---|---|---|
1 | 'Hello' | 1/1/1999 | == | 1 | 'Hello' | 1/1/1999 |
2 | 'Hello' | 1/1/1999 | != | 2 | 'Goodbye' | 1/1/1999 |
3 | 'Goodbye' | null | == | 3 | 'Goodbye' | null |
我希望使用关键字EXCEPT
来完成此操作,因为它不需要为每一列指定相等条件,也不需要在查询有非键列名称更改时更新查询.我知道在SELECT中使用通配符是一种糟糕的代码气味,但是这两个表将始终具有相同的非隐藏列,并且以这种方式编写过程将使代码更易于维护.
可能重要的是,表Table1
中的一个是时态表,而Table2
不是.然而,Table1
的历史记录存储在单独的表中,并且查询没有利用SYSTEM_TIME
(即,仅查询当前数据).
我try 过的东西
Table1
是使用以下脚本创建的:
CREATE TABLE Table1 (
ID INT NOT NULL PRIMARY KEY
, ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL
, ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL
, PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH (SYSTEM_VERSIONING = ON)
Table2
是使用以下脚本创建的:
CREATE TABLE Table2 (
ID INT NOT NULL PRIMARY KEY
)
我一直在try 的是以下内容,我认为应该删除Table1
中所有列都完全匹配的Table2
中的所有条目:
DELETE FROM [Table1]
WHERE [Table1].[ID] NOT IN (
SELECT ID FROM (
SELECT * FROM [Table1]
EXCEPT
SELECT * FROM [Table2]
) AS INNER_QUERY
)
但是,SQL Server会出现以下意外错误:
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
然而,下面的查询按预期工作,没有任何问题
SELECT * FROM [Table1]
WHERE [Table1].[ID] NOT IN (
SELECT ID FROM (
SELECT * FROM [Table1]
EXCEPT
SELECT * FROM [Table2]
) AS INNER_QUERY
)