我正在尝试在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
您是否可以帮助优化此查询。有没有其他方法可以得到这个正确的结果?
答案 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