【问题标题】:SQL Server 2008 R2: Combine two queries for optimizationSQL Server 2008 R2:结合两个查询进行优化
【发布时间】:2017-03-16 06:38:09
【问题描述】:

我有以下查询要优化。

Following 用于从利润表中获取详细信息。

  • 第一个内部 SELECT:在第一个 select 语句中,我必须从利润表中获取详细信息并为每一行分配行号。

  • 第二个内部 SELECT:在第二个 select 语句中,我必须进行一些计算(求和)。

  • 外部 SELECT:通过在 id 上组合它们来获得结果,并对数据进行一些操作。

代码:

SELECT  
    a.p_id, p_Name,
    convert(varchar, a.EndDate, 107) EndDate,
    convert(varchar, a.EndDate, 106) NewEndDate,
    LTRIM(a.p_id)) + '' + REPLACE(LEFT(CONVERT(VARCHAR, a.EndDate, 106), 6) + '' + RIGHT(CONVERT(VARCHAR, a.EndDate, 106), 2), ' ', '') as Compo,
    a.GP,           
    b.fpro FirstProfit,
    (b.fpro - b.spro) prodiff,
    a.Qtity * a.GP as Ov,
    a.Qtity,
    b.fproChanPer
FROM
    (SELECT 
         p_Name, p_id,
         EndDate,
         GP, FirstProfit,
         prodiff,
         Qtity,
         ROW_NUMBER() OVER (PARTITION By p_Name, p_id ORDER BY EndDate) Rown
     FROM   
         tbl_profit) a,
    (SELECT 
         p_id, 
         CAST(SUM(FirstProfit) AS DECIMAL(24,2)) fpro,
         CAST(SUM(SecondProfit) AS DECIMAL(24,2)) spro,
         CAST(CAST(SUM(prodiff) AS DECIMAL(24,2)) / CAST(SUM(SecondProfit) AS DECIMAL(24,2)) * 100 AS DECIMAL(24,2)) fproChanPer
     FROM 
         tbl_profit
     GROUP BY
         p_id) b    
WHERE 
    b.p_id = a.p_id 
    AND Rown = 1

我的问题:我可以结合这两个(别名 ab)内部 SELECT 语句进行查询优化吗?

我的尝试:我尝试使用以下查询得到不同的计算结果。

    SELECT  p_Name,
            p_id,
            EndDate,
            GP,
            FirstProfit,
            prodiff,
            Qtity
            ROW_NUMBER()OVER (PARTITION By p_Name,p_id ORDER By EndDate ) Rown,
            CAST(SUM(FirstProfit) AS DECIMAL(24,2)) fpro,
            CAST(SUM(SecondProfit) AS DECIMAL(24,2)) spro,
            CAST(CAST(SUM(prodiff) AS DECIMAL(24,2)) /CAST(SUM(SecondProfit) AS DECIMAL(24,2)) * 100 AS DECIMAL(24,2)) fproChanPer
    FROM    tbl_profit
    GROUP By p_id,p_Name,EndDate,GP,FirstProfit,prodiff,Qtity

【问题讨论】:

  • 不确定 Sql server 2008 是否支持SUM() OVER(),但如果支持,您可以使用单个内部选择。

标签: sql-server sql-server-2008-r2


【解决方案1】:

tbl_profit 必须有多个 P_Name 用于单个 p_id ,当您仅按 p_id 分组时,您将获得正确的聚合值,而由于单个 p_id 的多个 p_name 当您按 p_id 和 p_name 分组时,您的聚合总和值将加倍对于单个 p_id 有多个 p_name 的地方。

在这种情况下,您编写查询以获取 Rown = 1 记录的方式是完美的,认为仍有优化空间我做了一些事情,请检查。

SELECT
     a.p_id,
     p_Name,
     CONVERT(varchar, a.EndDate, 107) EndDate,
     CONVERT(varchar, a.EndDate, 106) NewEndDate,
     LTRIM(a.p_id) + '' + REPLACE(LEFT(CONVERT(varchar, a.EndDate, 106), 6) + '' + RIGHT(CONVERT(varchar, a.EndDate, 106), 2), ' ', '') AS Compo,
     a.GP,
     b.fpro AS FirstProfit,
     (b.fpro - b.spro) prodiff,
     a.Qtity * a.GP AS Ov,
     a.Qtity,
     b.fproChanPer
FROM (
    SELECT
         a.p_Name,
         a.p_id,
         a.EndDate,
         a.GP,
         a.FirstProfit,
         a.prodiff,
         a.Qtity,
         ROW_NUMBER() OVER (PARTITION BY a.p_Name, a.p_id ORDER BY a.EndDate) Rown
    FROM tbl_profit AS a WITH (NOLOCK)
    ) AS a
INNER JOIN 
    (
    SELECT
         b.p_id,
         CAST(SUM(b.FirstProfit) AS decimal(24, 2)) fpro,
         CAST(SUM(b.SecondProfit) AS decimal(24, 2)) spro,
         CAST(CAST(SUM(b.prodiff) AS decimal(24, 2)) / CAST(SUM(b.SecondProfit) AS decimal(24, 2)) * 100 AS decimal(24, 2)) fproChanPer
    FROM tbl_profit AS b WITH (NOLOCK)
    GROUP BY b.p_id
    ) AS b
ON b.p_id = a.p_id
     AND a.Rown = 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多