sql - 在 SQL 中使用累积需求时在聚合级别上优化表概览

标签 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 
...

最佳答案

我建议的避免重复代码的解决方案是创建一个 #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 中省略了requirement1='GROUP1')

关于sql - 在 SQL 中使用累积需求时在聚合级别上优化表概览,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51948819/

相关文章:

sql - 如果连续缺席 10 天,如何获取 FromDate 和 ToDate?

php - 在防止 SQL 注入(inject)方面,SQL Server 和 MySQL 之间有什么区别吗?

c# - 使用 CLR 存储过程在事务内记录 TSQL

python - 使用 Python 将 SQL 信息提取到 CSV 中,结果为空白

sql - PostgreSQL IS NULL 和长度

sql-server - 从 Sql Compact sdf 文件创建 Azure Sql 数据库

sql-server - 如何在没有数据的情况下进行sql数据库备份

python - sqlalchemy 批量插入比构建原始 SQL 慢

sql - 使用 over 子句运行总计

MySQL:如何将参数传递给触发器