具有聚合输出的SELECT语句中的子查询

时间:2014-10-27 18:03:57

标签: sql-server tsql group-by correlated-subquery

我正在尝试在Select语句中使用子查询和group by,但查询需要很长时间才能执行实际数据集,这将是几十万。

下面的示例数据集

CREATE TABLE #Temp1
(
Fkey INT,
BGkey INT,
Amt DECIMAL(10,4))          


CREATE TABLE #Temp2
(
Fkey INT,
CFkey INT,
Amt DECIMAL(10,4),
JobID INT,
PostedDate DATE)

INSERT INTO #Temp1
(Fkey,
BGkey,
Amt)

SELECT 1001,1,20.32
UNION ALL
SELECT 1002,2,10.32
UNION ALL
SELECT 1002,3,40.32

INSERT INTO #Temp2
(Fkey,
CFkey,
Amt,
JobID, PostedDate)

SELECT 1001,11,20.32,504, '2014-10-20'
UNION ALL
SELECT 1001,11,-20.32, NULL, '2014-10-27'
UNION ALL
SELECT 1001,13,20.32, 510, '2014-10-27'

预期的输出结果

CFKEY   BGKey   BGAMT   CFAmt
11  1   NULL    0
13  1   20.32   20.32

查询1输出 - >这是不正确的

查询1;

 Select CF.CFkey, BG.BGkey, SUM(BG.Amt) AS BGAmt, SUM(Cf.Amt) AS CFAmt  from #Temp2 CF
 INNER JOIN #Temp1 BG
 ON BG.Fkey = CF.Fkey
 WHERE CF.Fkey=1001
 group by CF.CFkey, BG.BGkey

查询1输出 - 这是错误的BGAmt加倍

CFkey   BGkey   BGAmt   CFAmt
11  1   40.64   0
13  1   20.32   20.32

查询2:获得预期结果,但实际数据集花费时间

 SELECT OUT.CFKEY,
 OUT.BGKey ,
 SUM(OUT.BGAMT) AS BGAMT,
 SUM(OUT.CFAmt) AS CFAmt FROM (
  Select CF.CFkey, BG.BGkey, 
  (SELECT T1.Amt from #Temp1 T1
    WHERE T1.Fkey = CF.Fkey
    AND CF.JobID IS NOT NULL
    AND CF.PostedDate IN ( SELECT MAX(T3.PostedDate) FROM #Temp2 T3
    WHERE T3.Fkey = CF.Fkey)) AS BGAMT,
Cf.Amt AS CFAmt from #Temp2 CF
 INNER JOIN #Temp1 BG
 ON BG.Fkey = CF.Fkey
 WHERE CF.Fkey=1001) AS OUT
 group by OUT.CFKEY,
 OUT.BGKey 

查询2 - 结果集[正确结果]但查询需要优化

CFKEY   BGKey   BGAMT   CFAmt
11  1   NULL    0
13  1   20.32   20.32

您是否可以帮助优化此查询。有没有其他方法可以得到这个正确的结果?

1 个答案:

答案 0 :(得分:0)

不是答案,但这是对它的看法的看法 这只是混乱 - 两个级别的#temp1和#temp2
你想做什么?

SELECT OUT.CFKEY, OUT.BGKey 
     , SUM(OUT.BGAMT) AS BGAMT
     , SUM(OUT.CFAmt) AS CFAmt 
  FROM (  Select CF.CFkey, BG.BGkey
                ,( SELECT T1.Amt 
                     from #Temp1 T1
                    WHERE T1.Fkey = CF.Fkey
                      AND CF.JobID IS NOT NULL
                      AND CF.PostedDate IN ( SELECT MAX(T3.PostedDate) 
                                               FROM #Temp2 T3
                                              WHERE T3.Fkey = CF.Fkey
                                           )
                 ) AS BGAMT
                ,Cf.Amt AS CFAmt 
            from #Temp2 CF
            JOIN #Temp1 BG
              ON BG.Fkey = CF.Fkey
           WHERE CF.Fkey=1001
       ) AS OUT
 group by OUT.CFKEY, OUT.BGKey 

你的命名在源头之后很难:

SELECT OUT.CFKEY, OUT.BGKey 
     , SUM(OUT.BGAMT) AS BGAMT
     , SUM(OUT.CFAmt) AS CFAmt 
  FROM (  Select Temp2a.CFkey, Temp1a.BGkey
                ,( SELECT Temp1b.Amt 
                     from #Temp1 Temp1b
                    WHERE Temp1b.Fkey = Temp2a.Fkey
                      AND Temp2a.JobID IS NOT NULL
                      AND Temp2a.PostedDate IN ( SELECT MAX(Temp2b.PostedDate) 
                                                   FROM #Temp2 Temp2b
                                                  WHERE Temp2b.Fkey = Temp2a.Fkey
                                               )
                 ) AS BGAMT
                ,Cf.Amt AS CFAmt 
            from #Temp2 Temp2a --CF
            JOIN #Temp1 Temp1a --BG
              ON Temp1a.Fkey = Temp2a.Fkey
           WHERE Temp2a.Fkey = 1001
       ) AS OUT
 group by OUT.CFKEY, OUT.BGKey

优化1:

SELECT OUT.CFKEY, OUT.BGKey 
     , SUM(OUT.BGAMT) AS BGAMT
     , SUM(OUT.CFAmt) AS CFAmt 
  FROM (  Select Temp2a.CFkey, Temp1a.BGkey
                ,( SELECT Temp1b.Amt 
                     from #Temp1 Temp1b
                    WHERE Temp1b.Fkey = Temp2a.Fkey
                      AND Temp2a.JobID IS NOT NULL
                      AND Temp2a.PostedDate IN ( SELECT MAX(Temp2b.PostedDate) 
                                                   FROM #Temp2 Temp2b
                                                  WHERE Temp2b.Fkey = 1001
                                               )
                 ) AS BGAMT
                ,Cf.Amt AS CFAmt 
            from #Temp2 Temp2a --CF
            JOIN #Temp1 Temp1a --BG
              ON Temp1a.Fkey = Temp2a.Fkey
             AND Temp2a.Fkey = 1001
       ) AS OUT
 group by OUT.CFKEY, OUT.BGKey

优化2 - 它可能不正确但它应该给你一些想法

SELECT OUT.CFKEY, OUT.BGKey 
     , SUM(OUT.BGAMT) AS BGAMT
     , SUM(OUT.CFAmt) AS CFAmt 
  FROM (  Select Temp2a.CFkey, Temp1a.BGkey, Temp1b.Amt, Temp2a.Amt AS CFAmt
               , Row_Number() (order by  Temp2a.PostedDate desc) as row                     
            from #Temp2 Temp2a --CF
            JOIN #Temp1 Temp1a --BG
              ON Temp1a.Fkey = Temp2a.Fkey
             AND Temp2a.Fkey = 1001
             AND Temp2a.JobID IS NOT NULL
       ) AS OUT
 where out.row = 1
 group by OUT.CFKEY, OUT.BGKey 
相关问题