首先的 - 這不是一個好的SQL查詢。每一列都被封裝在一個非sargable函數中,這意味着引擎將無法利用這些列上的任何索引(假設您有任何)。
首先讓我們來重寫這是一個半體面的SQL查詢:
SELECT i.*
FROM Input i
LEFT JOIN Production p
ON (p.CustID = i.CustID OR (p.CustID IS NULL AND i.CustID IS NULL))
AND (p.CustName = i.CustName OR (p.CustName IS NULL AND i.CustName IS NULL))
AND (p.Household = i.Household OR
(p.Household IS NULL AND i.Household IS NULL))
WHERE p.CustID IS NULL
現在,話雖如此,LEFT JOIN/IS NULL
不是很大的效率下去,但我們並沒有太多的選擇這裏,是因爲我們比較多列。根據你的列名,我開始懷疑這個模式是否被正確化了。一個CustID
應該最有可能與一個並且只有一個CustName
關聯 - 事實上,你必須比較這兩個似乎有點奇怪。和Household
- 我不確定這是什麼,但如果它是一個varchar(x)
/nvarchar(x)
列,那麼我想知道它是否也可能與客戶有1:1的關係。
如果我在這裏猜測太多,可隨意解開本段;但爲了以防萬一,我想說的是,如果這數據沒有正確標準化,規範化,將使它更容易和更快地對查詢:
SELECT *
FROM Input
WHERE CustID NOT IN (SELECT CustID FROM Production)
不管怎樣,回到第一個查詢,因爲這是我們現在需要處理的。不幸的是,這是不可能建立在LINQ的那些特定條件下加入的,所以我們需要重寫SQL查詢的東西略差(因爲我們現在有從Input
讀兩次):
SELECT *
FROM Input
WHERE <Primary Key> NOT IN
(
SELECT i.<Primary Key>
FROM Input i
INNER JOIN Production p
ON (p.CustID = i.CustID OR (p.CustID IS NULL AND i.CustID IS NULL))
AND (p.CustName = i.CustName OR (p.CustName IS NULL AND i.CustName IS NULL))
AND (p.Household = i.Household OR
(p.Household IS NULL AND i.Household IS NULL))
)
現在我們有一些我們最終可以轉化爲Linq語法。我們仍然不能明確地加入,這是最好的,但我們走老派,從笛卡爾連接開始,將連接條件拋到WHERE
段,服務器仍然可以將它整理出來:
var excluded =
from i in input
from p in production
where
((p.CustID == i.CustID) || ((p.CustID == null) && (i.CustID == null))) &&
((p.CustName == i.CustName) ||
((p.CustName == null) && (i.CustName == null))) &&
((p.Household == i.Household) ||
((p.Household == null) && (i.Household == null)));
select i.PrimaryKey;
var results =
from i in input
where !excluded.Contains(i.PrimaryKey)
select i;
我在這裏假設你在表上有某種主鍵。如果不這樣做,你有其他的問題,但你可以避開使用此特定問題EXCEPT
:
var excluded =
from i in input
from p in production
where
((p.CustID == i.CustID) || ((p.CustID == null) && (i.CustID == null))) &&
((p.CustName == i.CustName) ||
((p.CustName == null) && (i.CustName == null))) &&
((p.Household == i.Household) ||
((p.Household == null) && (i.Household == null)));
select i;
var results = input.Except(excluded);
SQL聯接不在這裏工作了,因爲它會從第二個表中返回的每一行的地方3列匹配。我只需要一行。列名僅用於說明。沒有主鍵和ID列不相關。每個表的ID都是唯一的,所以它不能被使用。你的LINQ給了我一些指針。謝謝。 – 2010-01-22 17:50:26
@Tony_Henrich:如果右表中有多個匹配的行,那麼你是對的,第一個查詢將返回重複的行。然而,我寫的後續查詢不會有這個問題,Linq查詢會做你想做的事情(包括最後一個如果沒有PK ......但我真的會建議不要PK,這個例子是一個很好的例子說明爲什麼它們很重要)。 – Aaronaught 2010-01-22 17:58:34
簡而言之,這些表格實際上是Excel電子表格。我已將數據複製到SQL Server以驗證操作。主鍵不會幫助,因爲沒有候選人。每個表中唯一的ID列對該表是唯一的。這些值在表格之間不匹配。 – 2010-01-22 18:28:35