2013-10-14 2 views
2

내가 3 개 테이블과 SQL 데이터베이스가 결과 (각 행이 고유) SQL - 쿼리 MAX 날짜의 결과를보고하거나 NULL이

  • Customer notes 마스터 데이터를 보유,

    1. Customer record 테이블을, 각 음표 데이터/시간 스탬프
    2. Product 테이블, 고객이 구입했습니다 보여주는 (많은 고객 당 메모 또는 전혀 없음이있을 수 있습니다)있는

      표 제품 : tbl_Customer_ 기록
      CustomerID를 ---- 회사 이름 ----- 회사 세그먼트 ----- 프로모션 코드

      테이블 : tbl_Customer_Notes
      CustomerID를 ---- 참고 ----- 작성 날짜

      테이블 :
      이 의 CustomerID가 ---- 제품 카테고리가

    내가 원하는 것은 당겨하는 것입니다 tbl_Customer_Products 최신 노트 만 포함하는 고객 레코드 목록이므로 여러 노트가있는 경우 중복되는 줄이 없습니다. 그러나 나는 또한 주 없음가있는 경우 고객 기록을 포함시키기를 원합니다. SELECT MAX 함수를 사용하여이 첫 번째 부분을 얻었고 잘 작동합니다. 문제는 마지막 코드 줄에 OR = NULL 절을 추가 할 때입니다. 이것은 작동하지 않으며 해결책을 찾을 수 없습니다.

    모든 의견을 크게 높이세요!

    SELECT   
    
    [tbl_Customer_Records].[CustomerID], 
    [tbl_Customer_Records].[Company Name], 
    [tbl_Customer_Records].[Company Segment], 
    [tbl_Customer_Records].[Promo Code], 
    [tbl_Customer_Notes].[Note], 
    [tbl_Customer_Products].[Product Category] 
    
    FROM    
    
    tbl_Customer_Records 
    LEFT OUTER JOIN tbl_Customer_Notes 
    ON tbl_Customer_Records.CustomerID = tbl_Customer_Notes.CustomerID 
    LEFT OUTER JOIN tbl_Customer_Products 
    ON tbl_Customer_Records.CustomerID = tbl_Customer_Products.CustomerID 
    
    WHERE 
    [Product Category] in ('Nuts','Bolts','Screws','Spanners') 
    
    AND 
    
    [Created Date] in (SELECT MAX ([Created Date]) FROM tbl.Customer_Notes GROUP BY [CustomerID]) 
    
    OR tbl_Customer_Note.Note is null 
    
  • 답변

    1

    이이 쿼리의 종류 할 (ROW_NUMBER 또는 그룹화 된 데이터와 결합) 할 수있는 몇 가지 트릭이있어,하지만 난 귀하의 경우 깨끗한 사람이 외부 사용하는 대부분의 생각이 적용

    select 
        cr.[CustomerID], 
        cr.[Company Name], 
        cr.[Company Segment], 
        cr.[Promo Code], 
        cn.[Note], 
        cp.[Product Category] 
    from tbl_Customer_Records as cr 
        left outer join tbl_Customer_Products as cp on cp.CustomerID = cr.CustomerID 
        outer apply (
         select top 1 
          t.[Note] 
         from tbl_Customer_Notes as t 
         where t.[CustomerID] = cr.[CustomerID] 
         order by t.[Created_Date] desc 
        ) as cn 
    where 
        cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners') 
    

    alias.column name 모든 서투른 table name.column name을 변경, 나는 훨씬 더 읽기 이런 식으로 생각합니다.

    또는 : 코드에 대한

    select 
        cr.[CustomerID], 
        cr.[Company Name], 
        cr.[Company Segment], 
        cr.[Promo Code], 
        cn.[Note], 
        cp.[Product Category] 
    from tbl_Customer_Records as cr 
        left outer join tbl_Customer_Products as cp on cp.CustomerID = cr.CustomerID 
        left outer join tbl_Customer_Notes as cn on 
         cn.CustomerID = cr.CustomerID and 
         cn.[Created_Date] = (select max(t.[Created_Date]) from tbl_Customer_Notes as t where t.CustomerID = cr.CustomerID) 
    where 
        cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners') 
    
    +0

    답변 해 주셔서 감사합니다.서투른 컬럼 이름에 대해 언급 할 때, 장래에 염두에 두겠다. 흥미롭게도 첫 번째 솔루션은 4,315 개의 결과를, 두 번째는 4,393 개의 결과를 반환합니다. 이는 Deepshikha의 솔루션과 동일합니다. 두 가지 제안을 해주셔서 감사 드리며, 향후 사용을 위해 구문을 기록하고 있습니다. 많은 시간을내어 도와 주셔서 감사합니다! Daniel – user1811852

    +0

    max (Created_Date)가 하나 이상인 레코드가있는 경우 첫 번째 레코드가 임의의 레코드를 반환합니다 –

    +0

    아, 이해합니다. 실제로 동일한 CreatedDate에 여러 노트가 있으므로 첫 번째 솔루션이이 상황에서 더 잘 작동합니다. 다시 한번 감사드립니다. (수락 된 대답이 변경됨). – user1811852

    0

    시도는 JOIN 연산자를 먼저 LEFT OUTER에서 왼쪽 테이블에서 행을 보존 만 가져 오기 바로 테이블에서 일치하는 행을 요구하는 CustomerID not in (select CustomerID from tbl_Customer_Note)

    1

    당신은 ON 조건에서 필터 조건을 추가 할 수 있습니다 사용할 수 있습니다. 다음 쿼리는 작동합니다 :

    SELECT   
    CR.[CustomerID], 
    CR.[Company_Name], 
    CR.[Company_Segment], 
    CR.[Promo_Code], 
    CN.[Note], 
    CP.[Product_Category] 
    FROM    
    tbl_Customer_Records CR 
    LEFT OUTER JOIN tbl_Customer_Notes CN 
    ON CR.CustomerID = CN.CustomerID AND CN.[Created_Date] in (SELECT MAX ([Created_Date]) 
                      FROM tbl_Customer_Notes 
                      WHERE CR.CustomerID = tbl_Customer_Notes.CustomerID 
                      GROUP BY [CustomerID]) 
    LEFT OUTER JOIN tbl_Customer_Products CP 
    ON CR.CustomerID = CP.CustomerID 
    WHERE 
    [Product_Category] in ('Nuts','Bolts','Screws','Spanners') 
    
    +0

    덕분에 - 정말 감사합니다. 이 코드를 실행하면 내 데이터 세트에 4,393 개의 결과가 반환되므로이 코드를 허용 된 대답으로 유지할 것입니다. 도움을 주셔서 감사합니다! 건배, Daniel – user1811852

    1

    작동합니다, NULL 값을 시도 :

    SELECT a.[CustomerID], 
         a.[Company Name], 
         a.[Company Segment], 
         a.[Promo Code], 
         a.[Note], 
         a.[Product Category] 
    FROM (
    SELECT   
    cr.[CustomerID], 
    cr.[Company Name], 
    cr.[Company Segment], 
    cr.[Promo Code], 
    cn.[Note], 
    cp.[Product Category], 
    ROW_NUMBER() OVER(PARTITION BY cr.[CustomerID] ORDER BY cn.[Created Date] DESC) as rnk 
    FROM tbl_Customer_Records cr 
    LEFT JOIN tbl_Customer_Notes cn 
    ON cr.CustomerID = cn.CustomerID 
    LEFT JOIN tbl_Customer_Products cp 
    ON cr.CustomerID = cp.CustomerID 
    WHERE cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners'))a 
    WHERE a.rnk = 1 
    
    +0

    코드에 대한 감사의 말씀을드립니다. 많은 감사를드립니다. 흥미롭게도이 코드는 제안 된 다른 솔루션보다 약간 적은 4049 개의 결과를 반환합니다. 감사! – user1811852