2014-10-27 3 views
0

Я пытаюсь использовать подзапрос и группу в инструкции Select, но запрос занимает много времени, чтобы выполнить с фактическим набором данных, который будет находиться в немногих 100 тысячах.Подзапрос в инструкции SELECT с агрегированным выходом

Пример набора данных ниже

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 выход -> это неверно

Query1;

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 outut - что некорректный BGAmt удваивается до

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

Запрос 2: Getting ожидаемого результата, но это требует время с фактическими данными установить

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 

Может кто-нибудь из вас поможет вам оптимизировать этот запрос. Есть ли другой способ получить этот правильный результат?

+0

Действительно ли вы выполняете этот запрос которые не имеют индексов или первичных ключей, или это только ради вопроса? –

+0

Вы знаете, что можете использовать синтаксис values ​​(),(),()? – Paparazzi

+0

Я использую ту же логику для разных наборов данных, которые находятся в тысячах, но для выполнения запроса требуется более часа. Так что нужно знать, есть ли какой-либо я могу оптимизировать логику, но получаю тот же ожидаемый результат? – user2380911

ответ

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