2014-12-10 3 views
17

저는 SQL 쿼리에 혼란 스럽습니다. 솔직히 말해서, Google에 대한 방법조차 잘 모르는 것들 중 하나입니다. 따라서 StackOverflow.이 하위 쿼리로 인해 오류가 발생하지 않는 이유는 무엇입니까?

나는 간단한 쿼리라고 생각합니다.

SELECT Id 
FROM Customer 
WHERE Id IN (SELECT Id from @CustomersWithCancelledOrders) 

여기 내가 이상한 점을 발견했습니다. @CustomersWithCancelledOrders 테이블 변수에 Id라는 열이 없습니다. 그러나 오류는 없습니다.

이 결과는 모든 고객의 ID입니다. 매 하나마다. 분명히 처음부터 서브 쿼리를 수행하는 것이 어려워집니다.

외부 테이블 (Customers)의 Id 열을 사용하는 것과 비슷하지만 왜 그렇게 할 수 있는지 이해할 수 없습니다. 당신이 그렇게하기를 원할 이유가 있습니까? 나는 엄청나게 분명한 것을 놓치고 있는가?

SQLFiddle 이상한. 해당 웹 사이트에서 여러 결과 집합을 반환 할 수있는 방법을 찾지 못해서 최고의 SQL Fiddle이 아니지만 문제를 어떻게 만났는지를 보여줍니다.

위의 "기능"에 대한 이름이 무엇인지, 왜 그것이 무엇인지, 그리고 잘못된 쿼리가 실제로 무엇을 의미하는지에 대한 정보가 있습니다.


나는 위의 질문을 약간 더 나은 예를 사용하도록 업데이트했습니다. 그것도 여전히 고안되었지만 실제로 문제가 발생했을 때 제가 쓴 스크립트에 더 가깝습니다.


상관 하위 쿼리에 대한 몇 가지 독서를하고 후에는 (서브 쿼리에서 잘못된 ID 열을 사용) 내 오타처럼 보이는 하위 쿼리의 동작을 변경합니다.

하위 쿼리의 결과를 한 번 평가 한 다음 그 결과를 집합으로 처리하는 대신 (의도 한대로) 외부 쿼리의 모든 행에 대해 하위 쿼리를 평가합니다.

이것은 하위 쿼리가 모든 행에 대해 서로 다른 결과 집합으로 평가되며 그 결과 집합에는 해당 행의 고객 ID가 보장됩니다. 부속 조회는 행 X의 x 번 반복 된 ID로 구성된 세트를 리턴합니다. 여기서 X는 선택되는 테이블 변수의 행 수입니다.

...

그것 정말 열심히이 문제에 대한 이해의 간결한 설명을 작성합니다. 죄송합니다. 나는 내가 지금 좋다라고 생각한다.

+0

우연히 알기가 어렵거나 유효한 케이스를 간소화했는데 대부분 하위 쿼리를 사용하는 대신 테이블을 조인해야합니다. – JamesRyan

+3

찾고있는 전문 용어는'상관 된 하위 쿼리 '입니다. – Brandon

+0

@JamesRyan 나는 어제 빠른 쿼리를 작성했고 우연히 위와 유사한 업데이트 쿼리를 작성했습니다. 하위 쿼리에서 외부 ID를 사용하는 것은 오타였으며 의도 한 하위 집합 대신 테이블의 모든 레코드를 업데이트 할 때 매우 놀랐습니다. –

답변

36

하위 쿼리에서 '외부 쿼리'열 이름에 액세스 할 수 있기 때문에 의도 된 동작입니다. Subquery 내에서 Table의 Id를 사용할 수 있다는 것을 의미하므로 질의는 Id를 사용한다고 생각합니다.

그래서 하위 쿼리를 사용할 때 별칭 또는 정규화 된 이름으로 한정해야합니다.

예 : 오류가 발생합니다
http://support.microsoft.com/kb/298674

+0

그 의도했던대로 동작을 명확히합니다. 그래도 쿼리는 실제로 무엇을 의미합니까? Id 값이에 설명 된 값 집합에있는 Table 내에서 Id 값을 모두 찾으십시오. –

+8

질의는 기본적으로 다음을 의미합니다 :'SELECT Id FROM Table WHERE Id IN (SELECT Table.Id FROM OtherTable)'어떤 이유에서, OtherTable에 행이있는 한 모든 것을 반환합니다. 하위 쿼리에 행이 있으면 하위 쿼리에서 모든 Table.Id를 선택합니다. 귀하의 바이올린 예제에서 CustomerMap에 삽입을 주석 처리하십시오. –

12
SELECT ID 
FROM [Table] 
WHERE ID IN (SELECT OtherTable.ID FROM OtherTable) 

이 확인하십시오. Allan S. Hanses가 말했듯이 하위 쿼리에서 기본 쿼리의 열을 사용할 수 있습니다.

SELECT ID 
FROM [Table] 
WHERE ID IN (SELECT ID) 
1

쿼리에 상관 서브 쿼리이며, 대부분 서브 쿼리에 의해 반환 된 열을 기반으로 외부 쿼리의 결과를 제한하는 데 사용되는 참조; 따라서 '상관 관계'. 이 예제에서 내부 쿼리의 ID는 실제로 외부 쿼리의 테이블 ID입니다. 이렇게하면 쿼리가 유효하지만 실제로 외부 쿼리와 내부 쿼리간에 상관 관계가 없으므로 유용한 결과를 얻지 못할 수 있습니다.

관련 문제