2011-08-10 4 views
4
SELECT MD.*, Contact.FirstName 
FROM MerchantData MD 
JOIN Merchant M ON M.MerchID = MD.MerchID 
JOIN (SELECT TOP 1 * FROM Location WHERE Location.BusID = MD.BusID) L ON L.BusID=MD.BusID 
AND L.Deleted = 0 
JOIN Contact ON Contact.ContactID = L.PrincipalID 

SQLSERVER 2008을 사용하고이 SQL 문을 쓰려고합니다. 한 번만 busid에 대한 여러 번 위치가 있으며 처음에만 발견에 참여하고 싶습니다. MD.BusID를 바인딩 할 수 없으므로 "Location.BusID = MD.BusID"부분에서 오류가 발생합니다. 이 조인에서 중첩 된 select statment에서 MD 테이블을 사용할 수 있습니까? 아니면이를 수행하는 다른 방법이 있습니까?T-SQL의 최상위 레코드에 합류

연락처 목록에 중첩 된 쿼리를 사용하여 데이터를 삽입하여 연락처 데이터를 driectly 취합니다. 그것은 간단하게 될 것

답변

8

나는 전체 결과 집합의 하위 쿼리가 생각 :

SELECT MD.*, Contact.FirstName 
FROM MerchantData MD 
JOIN Merchant M ON M.MerchID = MD.MerchID 
JOIN (SELECT BusID, MAX(PrincipalID) 
     FROM Location 
     WHERE Deleted = 0 
     GROUP BY BusID) L ON L.BusID=MD.BusID 
JOIN Contact ON Contact.ContactID = L.PrincipalID 

당신은 여전히 ​​JOINBusID 당 하나 개의 레코드를 가져가 있지만 상관 관계가 아닙니다.

+0

문제가 있습니다. MAX는 처음과 동일하지 않습니다. – Paparazzi

+1

그는 단지 하나의 'BusID'를 원하고 정렬 순서를 지정하지 않았습니다. 그가 선택한 경우 정렬 기준을 추가하는 것은 간단합니다. – JNK

+0

@JNK 문제는 subselect 후 L.Deleted = 0이므로이 경우에는 최대 삭제를 요청하는 것입니다. –

2

"그룹당 상위 n"문제입니다. 이 질문에 당신을 안내 할 것입니다 다음 BusID 경우 가상 테이블식이 BusID 당 최대 1 개 위치를 반환해야

SELECT MD.* , 
     Contact.FirstName 
FROM MerchantData MD 
JOIN Merchant  M ON M.MerchID = MD.MerchID 
JOIN (select * , 
       seq = rank() over(partition by BusID order by BusID , ...) 
     from Location 
     where L.Deleted = 0 
    ) L on L.BusID = MD.BusID 
     and seq  = 1 
JOIN Contact ON Contact.ContactID = L.PrincipalID 

(0 :

SQL Server query select 1 from each sub-group

당신이 같은 일을해야 할 것입니다 삭제되지 않은 위치가 없음).

+0

명시된 요구 사항은 첫 번째 항목을 살펴본 다음 처음 삭제 된 항목과 동일하지 않은 항목이 삭제되었는지 확인하는 것입니다. 그러나 당신의 솔루션은 우아하고 당신이하는 일을 명확하게 진술합니다. – Paparazzi

4
SELECT MD.*, Contact.FirstName 
FROM MerchantData MD 
JOIN Merchant M ON M.MerchID = MD.MerchID  
CROSS APPLY (SELECT TOP 1 * FROM Location WHERE BusID = MD.BusID AND DELETED = 0) L 
JOIN Contact ON Contact.ContactID = L.PrincipalID 
+0

+1 - 'CROSS APPLY'의 사용 – JNK

0

시도하고 오류를 찾아 내려면 시도해보십시오. Location.BusID = MD.BusID와 일치 할 수 있는지 확인하십시오.

SELECT MD.*, Contact.FirstName 
    FROM MerchantData MD 
    JOIN Merchant M ON M.MerchID = MD.MerchID 
    JOIN Location On Location.BusID = MD.BusID 

당신은 당신이 구문 작업을 진행되면 *이 너무

SELECT TOP 1 Location.BusID FROM Location WHERE Location.BusID = MD.BusID 

을 사용하여 사용하지 마십시오.

일단이 작업을 수행하면 "첫 번째"행과 일치하는지 확인한 다음 삭제되는지 확인합니다. 문제는 "첫 번째"행에 의한 순서가 없으면 임의적이라는 것입니다. 테이블에 클러스터 된 인덱스가 있어도 order by 절이없는 보장 된 정렬은 없습니다. 반복 가능한 대답을 얻으려면 정렬이 필요합니다. 그러나 정렬하는 경우 맨 위 행 만 있으면 MAX 또는 MIN과 그룹이보다 직선이됩니다.

하나 이상의 삭제 된 위치가있는 비즈니스를 원한다면 다음 작업은 효과가 있지만 그룹별로 열을 구분해야합니다. 두 개의 삭제 된 위치에 연락처 이름이 다르면 각각을보고합니다. 그래서, 이것은 당신이 찾고있는 것이 아닙니다.

SELECT MD.col1, MD.col2, Contact.FirstName 
    FROM MerchantData MD 
    JOIN Merchant M ON M.MerchID = MD.MerchID 
    JOIN Location L 
     ON L.BusID = MD.BusID 
     AND L.Deleted = 0 
    JOIN Contact ON Contact.ContactID = L.PrincipalID 
    GROUP BY MD.col1, MD.col2, Contact.FirstName