Sql server SQL Server 2008 R2:结合两个查询进行优化

Sql server SQL Server 2008 R2:结合两个查询进行优化,sql-server,sql-server-2008-r2,Sql Server,Sql Server 2008 R2,我需要优化以下查询 以下内容用于从利润表中获取详细信息 第一个内部选择:在第一个SELECT语句中,我必须从利润表中获取详细信息,并为每一行分配行号 第二个内部选择:在第二个SELECT语句中,我必须进行一些计算(sum) 外部选择:通过在id上组合它们来获得结果,并对数据进行一些操作 代码: 我的问题是:我可以将这两个(别名a和b)内部SELECT语句组合起来进行查询优化吗 我的尝试:我尝试使用以下查询,但得到了不同的计算结果 SELECT p_Name,

我需要优化以下查询

以下内容用于从利润表中获取详细信息

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

  • 第二个内部选择:在第二个SELECT语句中,我必须进行一些计算(sum)

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

代码:

我的问题是:我可以将这两个(别名
a
b
)内部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

tbl_profit必须为单个p_id设置多个p_名称,当您仅按p_id进行分组时,您将获得正确的聚合值,而由于为单个p_id设置多个p_名称,当您按p_id和p_名称进行分组时,如果单个p_id具有多个p_名称,则您的聚合和值将加倍

在这种情况下,您编写查询以获取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

tbl_profit必须为单个p_id设置多个p_名称,当您仅按p_id进行分组时,您将获得正确的聚合值,而由于为单个p_id设置多个p_名称,当您按p_id和p_名称进行分组时,如果单个p_id具有多个p_名称,则您的聚合和值将加倍

在这种情况下,您编写查询以获取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

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