퍼스트 -이 좋은 SQL 쿼리가 아닙니다. 모든 열은 sargable이 아닌 함수로 싸여 있습니다. 즉, 엔진이 해당 열의 인덱스를 이용할 수 없다는 것을 의미합니다. 반 괜찮은 SQL 쿼리로이를 다시 작성하여
하자의 시작 :
지금이,
LEFT JOIN/IS NULL
어느 효율성을 위해 좋은 것이 아니라 우리가이기 때문에 우리는 여기에 많은 선택의 여지가 없어 미루어
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
여러 열을 비교합니다. 귀하의 컬럼 이름을 바탕으로, 나는 스키마가 제대로 정상화되었는지 궁금해하기 시작했습니다. CustID
은 대부분 하나와 연관되어야합니다 CustName
- 두 가지를 모두 비교해야한다는 사실은 다소 이상하게 보입니다. 그리고 Household
- 나는 그것이 무엇인지 모르겠다. 그러나 그것이 varchar(x)
/nvarchar(x)
컬럼이라면 고객과 1 : 1의 관계가 있는지 궁금해한다.
내가 너무 많이 추측한다면이 단락을 기각 할 수있다. 하지만 단지의 경우, 나는 그것이 훨씬 쉽고 빠르게 쿼리 할 수 있도록 것입니다 정상화, 경우이 데이터가 제대로 정규화 아니라고 말하고 싶다 : 어쨌든
SELECT *
FROM Input
WHERE CustID NOT IN (SELECT CustID FROM Production)
, 첫 번째 쿼리에 다시 가고, 그게 지금 우리가해야 할 일이기 때문입니다. 불행하게도 그것은 LINQ에있는 그 특정 조건에 조인을 만들 수 없다, 그래서 우리는 (2 회 우리가 지금 Input
에서 읽을해야하기 때문에) 조금 더 뭔가로 SQL 쿼리를 다시 작성해야합니다
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가 나에게 몇 가지 조언을주었습니다. 감사. –
@ Tony_Henrich : 오른쪽 테이블에 일치하는 행이 여러 개 있으면 올바른 것입니다. 첫 번째 쿼리는 중복 행을 반환합니다. 그러나, 필자가 쓴 후속 쿼리는 그 문제가 없을 것이며, Linq 쿼리는 원하는 것을 할 것입니다. (PK가 없다면 마지막 것을 포함 해서요.하지만 PK가 없으면 정말 좋습니다.이 예제는 좋은 것입니다.) 그들이 왜 중요한지에 대한 그림). – Aaronaught
긴 이야기를 짧게하기 위해 테이블은 실제로 Excel 스프레드 시트입니다. 작업을 확인하기 위해 SQL Server에 데이터를 복사했습니다. 기본 키는 후보자가 없으므로 도움이되지 않습니다. 각 테이블의 고유 한 ID 열은 해당 테이블에 고유합니다. 테이블간에 값이 일치하지 않습니다. –