SQL-根据最大值加入查询

时间:2018-10-28 13:24:35

标签: sql sql-server subquery

我正在尝试将具有成本数据的CTE加入具有现有库存数据的另一CTE。我正在尝试使用主要的“现有” CTE,成本数据CTE(MAUCPvt)中只有1个值,这是每个WVG和商品代码的最新日期和最新序列。我附加了获得的结果和所需输出的图像。我相信这是子查询中的内容,因为我非常接近所需的输出,但是在这种情况下,我想忽略该项目。当我删除select max(project)时,我得到“子查询返回的值超过1”。这是我的查询:

With [MAUCPvt] as

(Select [Item], [Proj], [WVG], [Trans Date], [Warehouse], [Seq], 
isnull([MC00.010],0) as 'MC00.010', isnull([OC00.000],0) as 'OC00.000', isnull([GC00.025],0) as 'GC00.025',
isnull([MC00.010],0) + isnull([OC00.000],0) + isnull([GC00.025],0) as 'TotalCost'

 from
(
Select ltrim(w136.t_item) as 'Item', w136.t_cprj as 'Proj', w136.t_wvgr as 'WVG', w136.t_trdt as 'Trans Date',
w136.t_cwar as 'Warehouse', w136.t_seqn as 'Seq', w137.t_mauc_1 as 'MAUC', w137.t_cpcp as 'CostC' from twhina136100 w136

join twhina137100 w137 on w137.t_cprj = w136.t_cprj 
                        and w137.t_item = w136.t_item 
                        and w137.t_trdt = w136.t_trdt 
                        and w137.t_seqn = w136.t_seqn ) S

Pivot (SUM([MAUC]) for [CostC] in ([MC00.010],[OC00.000],[GC00.025]) ) PVT

)

, [OnHand] as

(Select ltrim(w260.t_item) as 'Part#', ITM.t_dsca as 'Part_Desc', w260.t_cwar as 'Warehouse', w200.t_wvgr as 'WVG', 
w260.t_cprj as 'ProjPeg', w260.t_cact as 'ProjAct', 

(w260.t_qhnd - w260.t_qnhd) as 'On Hand' ,

    STD.t_ecpr_1 as 'STD_COST'  

from twhwmd260100 w260 
join twhwmd200100 w200 on w200.t_cwar = w260.t_cwar
join tticpr007100 STD on STD.t_item = w260.t_item
join ttcibd001100 ITM on ITM.t_item = w260.t_item
--left join twhina135100 a135 on a135.t_wvgr = w200.t_wvgr and a135.t_cprj = w260.t_cprj and a135.t_item = w260.t_item
where w260.t_qhnd > 0 )

Select O.*,

    (Select m.TotalCost
    from MAUCPvt m 
    where m.Item = O.Part# and
        m.WVG = O.WVG and
        m.[Trans Date] = (Select MAX(mp.[Trans Date]) from MAUCPvt mp 
                                    where mp.Item = O.Part# and
                                        mp.Proj = O.ProjPeg and
                                        mp.WVG = O.WVG)
        and

        m.Seq = (Select MIN(mp.[Seq]) from MAUCPvt mp 
                                    where mp.Item = O.Part# and
                                        mp.Proj = O.ProjPeg and
                                        mp.WVG = O.WVG) 

        and

        m.Proj = (Select max(mp.Proj) from MAUCPvt mp
                                    where mp.Item = O.Part# and
                                        mp.Proj = O.ProjPeg and
                                        mp.WVG = O.WVG 
                                        )

        ) as 'MAUC_WVG'

from OnHand O
Where Part# = '140B00103'
Order by Part#, Warehouse 

-CTE 1

Item  Proj    WVG Trans Date  Warehouse   Seq MC00.010    OC00.000    GC00.025    TotalCost
140B00103     WVG002  12/24/2017  ZLOG-B  1   42.63   0   0   42.63
140B00103     WVG002  2/14/2018   BSHIP   1   40.25   0   0   40.25
140B00103     WVG002  6/1/2018    BCSHIP  1   40.25   0   0   40.25
140B00103     WVG002  10/17/2018  SCRAPD  1   40.25   0   0   40.25
140B00103     WVG002  10/22/2018  SCRAPD  1   40.25   0   0   40.25
140B00103 Z160029 WVG002  12/27/2017  ZLOG-B  1   42.63   0   0   42.63

-CTE2

Part#   Part_Desc   Warehouse   WVG ProjPeg ProjAct On Hand STD_COST
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  B   WVG001          48  40.25
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  BC  WVG001          1   40.25
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  D   WVG001          52  40.25
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  DC  WVG001          1   40.25
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  FSR01   WVG001          1   40.25
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  SCRAPD  WVG002          2   40.25
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  ZLOG-B  WVG002  Z160029 1001    2   40.25

-我的输出

Part#   Part_Desc   Warehouse   WVG ProjPeg ProjAct On Hand STD_COST    MAUC_WVG
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  B   WVG001          48  40.25   
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  BC  WVG001          1   40.25   
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  D   WVG001          52  40.25   
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  DC  WVG001          1   40.25   
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  FSR01   WVG001          1   40.25   
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  SCRAPD  WVG002          2   40.25   40.25
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  ZLOG-B  WVG002  Z160029 1001    2   40.25   42.63

-期望的输出

Part#   Part_Desc   Warehouse   WVG ProjPeg ProjAct On Hand STD_COST    MAUC_WVG
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  B   WVG001          48  40.25   
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  BC  WVG001          1   40.25   
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  D   WVG001          52  40.25   
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  DC  WVG001          1   40.25   
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  FSR01   WVG001          1   40.25   
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  SCRAPD  WVG002          2   40.25   40.25
140B00103   POT,10000 OHM,5%,2W,WIREWOUND,  ZLOG-B  WVG002  Z160029 1001    2   40.25   40.25

enter image description here

编辑::还尝试使用ROW_NUMBER(),但预期结果却需要> 12分钟才能完全运行,这是因为ROWNUMBER索引扫描。必须有一种简便的方法可以实现这一点。

With [MAUCPvt] as

(Select [Item], [Proj], [WVG], [Trans Date], [Warehouse], [Seq],
ROW_NUMBER() OVER (Partition by [Item] Order by [Item], [Trans Date]) as 'RN',
isnull([MC00.010],0) as 'MC00.010', isnull([OC00.000],0) as 'OC00.000', isnull([GC00.025],0) as 'GC00.025',
isnull([MC00.010],0) + isnull([OC00.000],0) + isnull([GC00.025],0) as 'TotalCost'

 from
(
Select ltrim(w136.t_item) as 'Item', w136.t_cprj as 'Proj', w136.t_wvgr as 'WVG', w136.t_trdt as 'Trans Date',
w136.t_cwar as 'Warehouse', w136.t_seqn as 'Seq', w137.t_mauc_1 as 'MAUC', w137.t_cpcp as 'CostC'
from twhina136100 w136

join twhina137100 w137 on w137.t_cprj = w136.t_cprj 
                        and w137.t_item = w136.t_item 
                        and w137.t_trdt = w136.t_trdt 
                        and w137.t_seqn = w136.t_seqn ) S

Pivot (SUM([MAUC]) for [CostC] in ([MC00.010],[OC00.000],[GC00.025])
 ) PVT

)
, 
[OnHand] as

(Select ltrim(w260.t_item) as 'Part#', ITM.t_dsca as 'Part_Desc', w260.t_cwar as 'Warehouse', w200.t_wvgr as 'WVG', 
w260.t_cprj as 'ProjPeg', w260.t_cact as 'ProjAct', 

(w260.t_qhnd - w260.t_qnhd) as 'On Hand' ,

    STD.t_ecpr_1 as 'STD_COST'  

from twhwmd260100 w260 
join twhwmd200100 w200 on w200.t_cwar = w260.t_cwar
join tticpr007100 STD on STD.t_item = w260.t_item
join ttcibd001100 ITM on ITM.t_item = w260.t_item
--left join twhina135100 a135 on a135.t_wvgr = w200.t_wvgr and a135.t_cprj = w260.t_cprj and a135.t_item = w260.t_item
where w260.t_qhnd > 0 )

Select top 1000 O.*,

    (Select m.TotalCost
    from MAUCPvt m 
    where m.Item = O.Part# and
        m.WVG = O.WVG and
        --m.Proj = O.ProjPeg and
        m.[RN] = (Select MAX(mp.RN) from MAUCPvt mp 
                                    where mp.Item = O.Part# and
                                        --mp.Proj = O.ProjPeg and
                                        mp.WVG = O.WVG)
        ) as 'MAUC_WVG'

from [OnHand] O
--Where Part# = '40980-15'
Order by Part#, Warehouse 

2 个答案:

答案 0 :(得分:0)

您可以尝试对子查询使用OUTER JOIN

SELECT distinct t2.*,t1.WAUC_WVG
FROM (
    SELECT *,(SELECT top 1 [TotalCost] FROM CTE1 ORDER BY TransDate desc) WAUC_WVG
    FROM CTE1
) t1
RIGHT JOIN CTE2 t2 on t1.WVG = t2.WVG and t1.Warehouse = t2.Warehouse

sqlfiddle

编辑

如果有很多Item,您可以尝试一下。

;with tradeCte as (
    SELECT *,ROW_NUMBER() OVER(PARTITION BY Item ORDER BY TransDate desc) rn
    FROM CTE1
)

SELECT distinct t2.*,t1.WAUC_WVG
FROM (
    SELECT *,(SELECT top 1 [TotalCost]
              FROM tradeCte tt
              WHERE tt.rn = 1 and tt.Item = t1.Item
              ORDER BY TransDate desc) WAUC_WVG 
    FROM tradeCte t1
) t1
RIGHT JOIN CTE2 t2 on t1.WVG = t2.WVG and t1.Warehouse = t2.Warehouse

答案 1 :(得分:0)

弄清楚了。通过在子查询中添加前1个,可以在15秒左右的时间内获得所需的结果,而使用ROW_NUMBER()则需要近15分钟。

With [MAUCPvt] as

(Select [Item], [WVG], [Trans Date],
isnull([MC00.010],0) as 'MC00.010', isnull([OC00.000],0) as 'OC00.000', isnull([GC00.025],0) as 'GC00.025',
isnull([MC00.010],0) + isnull([OC00.000],0) + isnull([GC00.025],0) as 'TotalCost'

 from
(
Select ltrim(w136.t_item) as 'Item', w136.t_cprj as 'Proj', w136.t_wvgr as 'WVG', w136.t_trdt as 'Trans Date',
w136.t_cwar as 'Warehouse', w136.t_seqn as 'Seq', w137.t_mauc_1 as 'MAUC', w137.t_cpcp as 'CostC'
from twhina136100 w136

join twhina137100 w137 on w137.t_cprj = w136.t_cprj 
                        and w137.t_item = w136.t_item 
                        and w137.t_trdt = w136.t_trdt 
                        and w137.t_seqn = w136.t_seqn ) S

Pivot (SUM([MAUC]) for [CostC] in ([MC00.010],[OC00.000],[GC00.025])
 ) PVT )
, 
[OnHand] as

(Select ltrim(w260.t_item) as 'Part#', ITM.t_dsca as 'Part_Desc', w260.t_cwar as 'Warehouse', w200.t_wvgr as 'WVG', 
w260.t_cprj as 'ProjPeg', w260.t_cact as 'ProjAct', 

(w260.t_qhnd - w260.t_qnhd) as 'On Hand' ,

    STD.t_ecpr_1 as 'STD_COST'  

from twhwmd260100 w260 
join twhwmd200100 w200 on w200.t_cwar = w260.t_cwar
join tticpr007100 STD on STD.t_item = w260.t_item
join ttcibd001100 ITM on ITM.t_item = w260.t_item
--left join twhina135100 a135 on a135.t_wvgr = w200.t_wvgr and a135.t_cprj = w260.t_cprj and a135.t_item = w260.t_item
where w260.t_qhnd > 0 )

Select O.*,

    (Select TOP 1 m.TotalCost
    from MAUCPvt m 
    where m.Item = O.Part# and
        m.WVG = O.WVG
    -- and m.[Seq] = (Select MIN(mp.Seq) from MAUCPvt mp 
    --                          where mp.Item = O.Part# and
    --                              mp.WVG = O.WVG)

     and m.[Trans Date] = (Select MAX(mp.[Trans Date]) from MAUCPvt mp
                                    where mp.Item = O.Part# and
                                        mp.WVG = O.WVG


        ) ) as 'MAUC_WVG'

from [OnHand] O
--Where Part# = '019612-2074'
Order by Part# asc , Warehouse asc