尝试使用对具有多个引用的表的单数引用来加入SQL Server表

时间:2017-01-19 14:08:10

标签: sql sql-server sql-server-2012

我有一个问题我创建了去年我所有接收器的总数,我们返回的所有产品以及原因。我遇到的问题是如何正确地将表格与每个客户的总接收者和表格中的问题列表正确地连接起来。

当我进行连接时,我最终得到了来自接收器表的总和重复。我理解为什么会这样,我只是不知道如何解决它。

FirstCTE

Receiver Qty     fvendno
---------------------------
   21             ACO   
    2             AEG   
   16             AER   
  139             AET 

SecondCTE

fdincidate    Fkey_ID   fcvendno    FPROBLEM
-----------------------------------------------------
3/8/16 9:57     2451    AET     Wrong Quantity      
3/8/16 9:59     2452    AET     Wrong Quantity      
4/18/16 10:41   2527    AET     Wrong Quantity      
4/28/16 11:57   2540    AET     Defective Material  
6/24/16 14:19   2595    AET     Wrong Material      
11/2/16 10:51   2700    AET     Wrong Material      
12/1/16 12:29   2804    AET     Wrong Material      
1/9/17 14:40    2838    AET     Wrong Material      
1/18/05 16:02   122     AIN                         
11/4/15 11:52   2316    ALF     Wrong Quantity      
6/2/14 10:58    1565    AVL     Wrong Quantity      
6/2/14 12:24    1567    AVL     Defective Material 

查询:

SELECT        
    ap.fcompany, 
    FC.[Receiver Qty], 
    COUNT(SC.FKey_ID) AS 'Number of issues per vendor',
    CASE sc.FPROBLEM 
       WHEN 'Wrong Quantity' 
          THEN 'Shortage' 
       WHEN 'Defective Material' 
          THEN 'Defective Material' 
       WHEN 'Wrong Material' 
          THEN 'Wrong Material' 
    END AS fproblem
FROM            
    SecondCTE AS SC 
LEFT OUTER JOIN 
    FirstCTE AS FC ON FC.fvendno = SC.fcvendno 
LEFT OUTER JOIN
    apvend AS ap ON SC.fcvendno = ap.fvendno
WHERE 
    (SC.fdincidate BETWEEN DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) - 1, 0) 
                       AND DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE()) -1, -1))
GROUP BY 
    FC.[Receiver Qty], ap.fcompany, SC.FPROBLEM
ORDER BY 
    ap.fcompany, SC.FPROBLEM

我想要的结果

fcompany  Receiver Qty  Number oF issues per vendor  fProblem
A           139            1                         Defective Material
A                          3                         Wrong Material
A                          3                         Shortage
B           597            2                         Defective Material
B                          2                         Wrong Material
C           16             3                         Shortage
D           13             3                         Shortage
E           400            25                        Shortage
F           10             1                         Defective Material
G           90             1                         Shortage

我得到的结果

fcompany  Receiver Qty  Number or issues per vendor   fProblem
---------------------------------------------------------------
A           139                 1                     Defective Material
A           139                 3                     Wrong Material
A           139                 3                     Shortage
B           597                 2                     Defective Material
B           597                 2                     Wrong Material
C           16                  3                     Shortage
D           13                  3                     Shortage
E           400                 25                    Shortage
F           10                  1                     Defective Material
G           90                  1                     Shortage

2 个答案:

答案 0 :(得分:1)

使用 row_number() [Reciver Qty]的重复实例设置为null:

, thirdcte as (
    select
        ap.fcompany
      , fc.[Reciver Qty]
      , [Number of issues per vendor] = count(sc.fkey_id) 
      , fproblem = case sc.fproblem when 'Wrong Quantity' then 'Shortage' 
                         when 'Defective Material' then 'Defective Material' 
                         when 'Wrong Material' then 'Wrong Material' 
                         end 
      , rn = row_number() over (
           partition by ap.fcompany 
           order by (case sc.fproblem when 'Wrong Quantity' then 'Shortage' 
           when 'Defective Material' then 'Defective Material' 
           when 'Wrong Material' then 'Wrong Material' 
           end)
        )
     from Secondcte as sc 
      left outer join Firstcte as fc on fc.fvendno = sc.fcvendno 
      left outer join apvend as ap on sc.fcvendno = ap.fvendno
     where (sc.fdincidate between dateadd(year, datediff(year, 0, getdate()) - 1, 0) 
            and dateadd(month, datediff(month, - 1, getdate()) - 1, - 1))
     group by fc.[Reciver Qty]
        , ap.fcompany
        , sc.fproblem
)

select 
      fcompany
    , [Reciver Qty] = case when rn = 1 then [Reciver Qty] else null end
    , [Number of issues per vendor]
    ,  fproblem
  from thirdcte
  order by fcompany, fproblem

注意:请注意 between Bad habits to kick : mis-handling date / range queries - Aaron Bertrand - 2009-10-16

答案 1 :(得分:0)

如果我正确阅读了您的问题,您希望在前一条记录具有相同值时清空Reciver。您可以使用LAG() - 函数:

WITH result AS (

    SELECT        ap.fcompany, FC.[Reciver Qty], COUNT(SC.FKey_ID) AS 'Number of issues per vendor'
    , CASE sc.FPROBLEM WHEN 'Wrong Quantity' THEN 'Shortage' 
                       WHEN 'Defective Material' THEN 'Defective Material' 
                       WHEN 'Wrong Material' THEN 'Wrong Material' 
                       END AS fproblem
     FROM            SecondCTE AS SC left OUTER JOIN FirstCTE AS FC 
                              ON FC.fvendno = SC.fcvendno LEFT OUTER JOIN
                              apvend AS ap 
                              ON SC.fcvendno = ap.fvendno
     WHERE (SC.fdincidate BETWEEN DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) - 1, 0) AND DATEADD(MONTH, DATEDIFF(MONTH, - 1, GETDATE()) - 1, - 1))
     GROUP BY FC.[Reciver Qty]
     , ap.fcompany
     , SC.FPROBLEM
)

SELECT fcompany
, ISNULL(NULLIF(Reciver, LAG(Reciver,1,0) OVER (ORDER BY fcompany, FPROBLEM)),'') AS Reciver
, [Qty Number of issues per vendor]
, fProblem
from result
 ORDER BY fcompany
 , FPROBLEM