如何对临时表中的行执行求和并将顶部的总行作为汇总?

时间:2017-01-31 15:11:58

标签: sql-server

我有一个临时表,我插入10行。

他们看起来像这样:

COL1    COL2            COL3
Jobs    ALL SALARIES    AVG SALARIES
19      $2,286,232.00   $285,779.00 -- THIS IS THE SUMMARY ROW AT THE TOP
0       0               0
1       $386,156.00     $96,539.00
2       $923,520.00     $153,920.00
1       $626,200.00     $469,650.00
7       $2,772,400.00   $440,000.00
0       0               0
3       $2,203,200.00   $61,200.00
1       $153,000.00     $102,000.00
3       $1,752,816.00   $213,783.00
1       $408,000.00     $204,000.00

第一行是ROLL UP行,所有内容都需要按此顺序排列,但是,第一行是总行,正如您所看到的,它不正确。

行1应为:

19      $11,682,164.00  $217636.50

我正在表演     SUM(CONVERT(数字(18,2),col2))OVER()为col2 和     AVG(CONVERT(数字(18,2),col3))为col3

但正如你所看到的,这是不正确的。

注意:$和,原始SQL中没有,我只是为了清楚而把它放在那里。

最后,这是产生上述,准正确的SQL ......

    select TOP(9) PW_WAGE_LEVEL,
        CONVERT(numeric(18,2),CASE WHEN WAGE_RATE_OF_PAY_TO = '0.00' THEN
            CASE WHEN ANNUALIZED_SALARY = '0.00' THEN
                CASE WHEN pw_unit_of_pay = 'year' THEN
                    CAST(REPLACE(WAGE_RATE_OF_PAY_FROM,',','') as numeric)
                END
            ELSE
                CAST(REPLACE(MIDPOINT_WAGE_RATE,',','') as numeric)
            END
        ELSE 
            CASE WHEN WAGE_RATE_OF_PAY_TO = '0.00' THEN
                CASE WHEN pw_unit_of_pay = 'hour' THEN
                    CAST(REPLACE(ANNUALIZED_SALARY,',','') as numeric)
                ELSE
                    CAST(REPLACE(ANNUALIZED_SALARY,',','') as numeric)
                END
            ELSE 
                CASE WHEN WAGE_RATE_OF_PAY_TO > '0.00' THEN
                    CASE WHEN pw_unit_of_pay = 'hour' THEN
                        CASE WHEN ANNUALIZED_SALARY = '0.00' THEN
                            CAST(REPLACE(MIDPOINT_WAGE_RATE,',','') as numeric)
                        ELSE
                            CAST(REPLACE(ANNUALIZED_SALARY,',','') as numeric)
                        END
                    END
                END
            END
        END * pw_wage_level) as ttlWagesPerLevel,
        SUM(CONVERT(numeric(18,2),CASE WHEN WAGE_RATE_OF_PAY_TO = '0.00' THEN
            CASE WHEN ANNUALIZED_SALARY = '0.00' THEN
                CASE WHEN pw_unit_of_pay = 'year' THEN
                    CAST(REPLACE(WAGE_RATE_OF_PAY_FROM,',','') as numeric)
                END
            ELSE
                CAST(REPLACE(MIDPOINT_WAGE_RATE,',','') as numeric)
            END
        ELSE 
            CASE WHEN WAGE_RATE_OF_PAY_TO = '0.00' THEN
                CASE WHEN pw_unit_of_pay = 'hour' THEN
                    CAST(REPLACE(ANNUALIZED_SALARY,',','') as numeric)
                ELSE
                    CAST(REPLACE(ANNUALIZED_SALARY,',','') as numeric)
                END
            ELSE 
                CASE WHEN WAGE_RATE_OF_PAY_TO > '0.00' THEN
                    CASE WHEN pw_unit_of_pay = 'hour' THEN
                        CASE WHEN ANNUALIZED_SALARY = '0.00' THEN
                            CAST(REPLACE(MIDPOINT_WAGE_RATE,',','') as numeric)
                        ELSE
                            CAST(REPLACE(ANNUALIZED_SALARY,',','') as numeric)
                        END
                    END
                END
            END
        END) * pw_wage_level) OVER() as ttlWages,
        SUM(pw_wage_level) OVER() as ttlPTFTJobs
from myFirstTempTable
where worksite_state = 'RI'
and JOB_TITLE like '%accountant%'
group by pw_unit_of_pay,pw_wage_level,ANNUALIZED_SALARY

更新:

实际的SCHEMA就像这样进入TEMP TABLE:

USE [myFirstTempDB]
GO
/****** Object:  StoredProcedure [dbo].[usp_call_homepage_report]    Script Date: 1/9/2017 10:07:52 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[usp_call_homepage_report]        
    @wsCity varchar(255),
    @wsState varchar(10),
    @pwUOP varchar(10),
    @jobTitle varchar(255)

    AS
        BEGIN   

        --CREATE A TEMP TABLE first... we need somewhere to stick the data
        IF OBJECT_ID ('tempdb..#tempHomePageResults') is not null
        drop table #tempHomePageResults

        DECLARE @tempHomePageResults TABLE (
            TotalNbrPTandFTJobs varchar(50), 
            TotalAnnualWages varchar(50), 
            TotalAvgSalary varchar(50))

                INSERT INTO @tempHomePageResults
                execute usp_row1_homePageReport @wsCity,@wsState,@pwUOP,@jobTitle
                --BLANK ROW - FULL TIME SPECIALTY JOBS...
                INSERT INTO @tempHomePageResults
                (TotalNbrPTandFTJobs, TotalAnnualWages,TotalAvgSalary)
                VALUES(1,0,0)
                --SKILL LEVEL ROWS!
                --FT JOB SKILL LEVEL ROWS!              
                INSERT INTO @tempHomePageResults
                execute usp_row1_6_HomePageReport @wsCity,@wsState,@pwUOP,@jobTitle,'Y',1
                INSERT INTO @tempHomePageResults
                execute usp_row1_6_HomePageReport @wsCity,@wsState,@pwUOP,@jobTitle,'Y',2
                INSERT INTO @tempHomePageResults
                execute usp_row1_6_HomePageReport @wsCity,@wsState,@pwUOP,@jobTitle,'Y',3
                INSERT INTO @tempHomePageResults
                execute usp_row1_6_HomePageReport @wsCity,@wsState,@pwUOP,@jobTitle,'Y',4
                --BLANK ROW - PART TIME SPECIALTY JOBS...
                INSERT INTO @tempHomePageResults
                (TotalNbrPTandFTJobs,
                TotalAnnualWages,TotalAvgSalary)
                VALUES(2,0,0)
                --SKILL LEVEL ROWS!
                --PT JOB SKILL LEVEL ROWS!              
                INSERT INTO @tempHomePageResults
                execute usp_row1_6_HomePageReport @wsCity,@wsState,@pwUOP,@jobTitle,'N',1
                INSERT INTO @tempHomePageResults
                execute usp_row1_6_HomePageReport @wsCity,@wsState,@pwUOP,@jobTitle,'N',2
                INSERT INTO @tempHomePageResults
                execute usp_row1_6_HomePageReport @wsCity,@wsState,@pwUOP,@jobTitle,'N',3
                INSERT INTO @tempHomePageResults
                execute usp_row1_6_HomePageReport @wsCity,@wsState,@pwUOP,@jobTitle,'N',4                           

                SELECT * FROM @tempHomePageResults

END 

注意:我知道这是“非”规范化,但它是从CSV到SQL SERVER的快速导入,并且有一个TIME CRUNCH。

可能更适合将正确的数据类型规范化为:

INT NUMERIC(18,2) NUMERIC(18,2)

因此,确定NORMALIZED数据:

COL1    COL2            COL3
Jobs    ALL SALARIES    AVG SALARIES
19      2286232.00      285779.00 -- THIS IS THE SUMMARY ROW AT THE TOP
0       0               0
1       386156.00       96539.00
2       923520.00       153920.00
1       626200.00       469650.00
7       2772400.00      440000.00
0       0               0
3       2203200.00      61200.00
1       153000.00       102000.00
3       1752816.00      213783.00
1       408000.00       204000.00

希望这有助于你帮助我。

由于

1 个答案:

答案 0 :(得分:1)

这是我的答案:将总和排在最前面是很容易的。问题是:其他行将如何出现?临时表中的任何内容都不允许我们为其余行生成任何可靠的排序。请记住,仅仅因为您按给定顺序插入行,您不能指望它们以相同的顺序出现。我们将是一个简单的

ORDER BY TotalAnnualWages DESC

但我认为你想要插入它们的顺序中的其他行。所以,我会在你的表中添加一个标识列:

CREATE TABLE dbo.tempHomePageResults  (
        ID INTEGER IDENTITY(1,1) PRIMARY KEY ,
        TotalNbrPTandFTJobs INTEGER, 
        TotalAnnualWages NUMERIC(12,2), 
        TotalAvgSalary NUMERIC(12,2))

完成后,以下内容将首先对最大行进行再次运算,然后再对每行进行后续运算

WITH CTE AS 
 (SELECT res.TotalNbrPTandFTJobs, res.TotalAnnualWages, res.TotalAvgSalary, 
 ROW_NUMBER() OVER(ORDER BY res.TotalAnnualWages DESC) AS RN,
 res.ID
 FROM dbo.tempHomePageResults res
 )
SELECT cte.TotalNbrPTandFTJobs, cte.TotalAnnualWages, cte.TotalAvgSalary
  FROM CTE
ORDER BY CASE WHEN cte.RN =1 THEN RN ELSE 2 END, 
  cte.ID

所以,这样,最大行(RN = 1)首先出现,每隔一行按照你插入它们的顺序排列。

更新ADAM的答案:

enter image description here

更新ADAM的最后评论和我的关于 - 窗口函数只能出现在SELECT或ORDER BY子句中。

此声明出现""最后一次进入@tempHomePageResults表并进入最终" END"声明。 (参见上面的代码)

            BEGIN
                UPDATE @tempHomePageResults SET
                    TotalAnnualWages = CAST(SUM(CONVERT(numeric(18,2),TotalAnnualWages)) OVER() as varchar),
                    TotalAvgSalary = AVG(CAST(CONVERT(numeric(18,2),TotalAvgSalary) as varchar))
                WHERE h1bID = 0
            END