在SQL中使用累积需求时,在汇总级别上优化表概述

时间:2018-08-21 12:35:06

标签: sql sql-server

我正在尝试找到一种最佳方法来获取正在累计显示的汇总概览的概览,即通过扣除未满足每个步骤中累积要求的观察值。

这是表脚本和示例数据:

CREATE TABLE #Table_A(
   id           INTEGER  NOT NULL PRIMARY KEY 
  ,totalAmount  INTEGER  NOT NULL
  ,requirement1 VARCHAR(6) NOT NULL
  ,requirement2 INTEGER  NOT NULL
  ,requirement3 BIT  NOT NULL
  ,requirement4 VARCHAR(10) NOT NULL
);
INSERT INTO #Table_A(id,totalAmount,requirement1,requirement2,requirement3,requirement4) VALUES (1,6580,'GROUP1',100,0,'TEST');
INSERT INTO #Table_A(id,totalAmount,requirement1,requirement2,requirement3,requirement4) VALUES (2,3667,'GROUP1',100,1,'PRODUKTION');
INSERT INTO #Table_A(id,totalAmount,requirement1,requirement2,requirement3,requirement4) VALUES (3,2907,'GROUP1',100,1,'TEST');
INSERT INTO #Table_A(id,totalAmount,requirement1,requirement2,requirement3,requirement4) VALUES (4,5271,'GROUP2',100,1,'TEST');
INSERT INTO #Table_A(id,totalAmount,requirement1,requirement2,requirement3,requirement4) VALUES (5,91630,'GROUP1',200,0,'PRODUKTION');
INSERT INTO #Table_A(id,totalAmount,requirement1,requirement2,requirement3,requirement4) VALUES (6,9925,'GROUP1',100,1,'TEST');
INSERT INTO #Table_A(id,totalAmount,requirement1,requirement2,requirement3,requirement4) VALUES (7,4730,'GROUP1',100,1,'TEST');
INSERT INTO #Table_A(id,totalAmount,requirement1,requirement2,requirement3,requirement4) VALUES (8,5171,'GROUP2',100,1,'TEST');
INSERT INTO #Table_A(id,totalAmount,requirement1,requirement2,requirement3,requirement4) VALUES (9,1250,'GROUP1',100,1,'TEST');
INSERT INTO #Table_A(id,totalAmount,requirement1,requirement2,requirement3,requirement4) VALUES (10,11223,'GROUP1',100,1,'TEST');

这是我要实现的概述:

+------+-------------+-------+-----------+
| step | totalAmount | total |  comment  |
+------+-------------+-------+-----------+
| 1    | 40282       | 7     | comment 1 |
| 2    | 30035       | 5     | comment 2 |
| ...  | ...         | ...   | ...       |
| n    | X           | Y     | comment n |
+------+-------------+-------+-----------+

最后,这是我到目前为止已完成的SQL代码:

-- drop tables if they exists
drop table if exists #table_step1
drop table if exists #table_step2

-- select data from the different steps
-- select data step 1
select *
into #table_step1
from #Table_A
where
    requirement1 = 'GROUP1'
    and requirement2 = 100

-- select data step 2
select * 
into #table_step2
from #table_step1
where 
    requirement3 = 1
    and requirement4 = 'TEST'
...

-- aggregate the data for each step and use UNION ALL to get overall overview
select 1 as step, sum(totalAmount) as totalAmount, count(*) as total, 'comment 1' as comment
from #table_step1

UNION ALL

select 2 as step, sum(totalAmount) as totalAmount, count(*) as total, 'comment 2' as comment
from #table_step2 

UNION ALL 
...

2 个答案:

答案 0 :(得分:1)

如何使用Common Table Expressions代替临时表?

示例:

WITH STEP1 AS
(
  select id, totalAmount, requirement1, requirement2, requirement3, requirement4 
  from #Table_A
  where requirement1 = 'GROUP1' 
    and requirement2 = 100
)
, STEP2 AS
(
  select * from STEP1
  where requirement3 = 1 
    and requirement4 = 'TEST'

)
, STEP3 AS
(
  select * from STEP2
  where totalAmount >= 5000
)
SELECT 1 AS Step, SUM(totalAmount) AS TotalAmount, COUNT(*) AS Total, 'comment 1' AS Comment
FROM STEP1
UNION ALL
SELECT 2, SUM(totalAmount), COUNT(*), 'comment 2' FROM STEP2
UNION ALL
SELECT 3, SUM(totalAmount), COUNT(*), 'comment 3' FROM STEP3

答案 1 :(得分:1)

我为避免重复代码而提出的解决方案是创建一个#step表,在其中将对n个步骤中的每一个放置需求检查(在每种情况下均未检查时为NULL),然后使用while循环插入最终代码#results列出您需要的内容(实际上每次迭代都与一个并集所有行相同)

create table #result (step int,totalAmount bigint,total bigint,comment varchar(max))

create table #step(
    step int
    ,comment_text varchar(max)
    ,requirement1 VARCHAR(6) NULL
    ,requirement2 INTEGER  NULL
    ,requirement3 BIT  NULL
    ,requirement4 VARCHAR(10) NULL)

-- Note: initially you have NOT NULL on all requirements: So you can use NULL when a step does not need to check the requirement
insert #step values 
    (1,'comment 1','GROUP1',100,NULL,NULL),
    (2,'comment 2','GROUP1',NULL,1,'TEST')

declare @step int=1

while(@step<=2)
begin
    insert #result
        select @step, sum(a.totalAmount), count(*) as total, max(s.comment_text)
        from #step s
        inner join #Table_A a on 
            (s.requirement1 is null or s.requirement1=a.requirement1)
        and (s.requirement2 is null or s.requirement2=a.requirement2)
        and (s.requirement3 is null or s.requirement3=a.requirement3)
        and (s.requirement4 is null or s.requirement4=a.requirement4)
        where s.step=@step
    set @step+=1
end

我对此进行了测试,其#result结果与您的规格一致(不过我假设您在步骤2中省略了require1 ='GROUP1')