Sql-Server

select 中的 Where 子句不適用於 guid 的不等式

  • August 28, 2019

我想查詢我們的CRM Db. 我有一個備份CRM Db和現有的。有一個custom entity,在他們兩個我都創建了。我的一些自定義實體記錄已從現有數據庫中刪除。我想比較哪些記錄已刪除。現有記錄數為 17,備份包含 19 條記錄。自定義實體名為new_services。備份數據庫被命名test2,現有一個是MSCRM表名是new_services當我查詢這個相等的時:

select * from test2.dbo.new_services as t1,
MSCRM.dbo.new_services as t2
where t1.new_service_Id = t2.new_service_Id;

並返回正確的記錄,但是當我嘗試這個時:

select * from test2.dbo.new_services as t1,
MSCRM.dbo.new_services as t2
where t1.new_service_Id != t2.new_service_Id;

它返回 308 records!new_service_id 是記錄的 guid。哪裡錯了?

您的邏輯是錯誤的;-) 假設有兩個表:

CREATE TABLE T1 ( x int not null );
INSERT INTO T1 (x) VALUES (1),(2),(3),(4);

CREATE TABLE T2 ( x int not null );
INSERT INTO T2 (x) VALUES (1),(12),(13),(14);

您的第一個範例將返回 1 行:

SELECT * 
FROM T1
JOIN T2
   ON T1.x = T2.x

1  1

而您的第二個範例將返回 4*4 - 1 = 15 行。如果您考慮一下,在一組 4x4=16 行中,其中 1 行謂詞為真,如果謂詞為假,則有多少行?

您可能正在尋找的是 MINUS 或 EXCEPT(不確定它在 sql-server 中的名稱):

SELECT * from test2.dbo.new_services
EXCEPT
SELECT * from MSCRM.dbo.new_services

或者可能反過來(不確定哪個表是哪個)

編輯:正如評論中指出的 MySQL(不確定最新版本),不支持基本的集合操作 INTERSECT 和 EXCEPT。EXCEPT 是 SET MINUS,可以使用 NOT EXISTS 或 NOT IN 來實現:

SELECT t1.* FROM T
WHERE NOT EXISTS (
   SELECT 1 FROM T2 WHERE T1.... = T2... AND ...
);

另一種選擇是使用 OUTER JOIN。

值得注意的是,EXCEPT ALL由於保留了 T1 中的任何重複項,因此上述對應。對於真正的EXCEPT運算符,應使用 DISTINCT:

SELECT DISTINCT t1.* FROM T
WHERE NOT EXISTS (
   SELECT 1 FROM T2 WHERE T1.... = T2... AND ...
);

我不會深入研究 null 的陰影地帶,以及它對錶達式之間邏輯相等的影響

另一方面,INTERSECT 與乘法密切相關。我們可以以與上述相同的方式使用 IN 或 EXISTS 謂詞來模擬它。

引用自:https://dba.stackexchange.com/questions/246410