在SQL中分配新的局部变量要求

时间:2018-08-20 13:24:37

标签: sql sql-server

我是在SQL中使用DECLARE,SET和EXEC()的新手,所以也许我的方法不适用于此问题,所以请耐心等待。我的目标是减少重复代码的使用。我目前有很多联合声明,其中WHERE子句是累积的。代码的一部分看起来像这样(对于这篇文章来说太长了):

编辑1:初始代码

-- step 1
select 1 as step, sum(Amount) as totalValue, count(*) as total, 'comment 1' as comment
from table_A
Where 
    requirement1 = 1
    and requirement2 = 100
    and requirement3 = 'A'
-- step 2
union
select 2 as step, sum(Amount) as totalValue, count(*) as total, 'comment 2' as comment
from table_A
Where 
    requirement1 = 1
    and requirement2 = 100
    and requirement3 = 'A'
    and requirement4 = 50
union
.
.
.
-- step n
union
select n as step, sum(Amount) as totalValue, count(*) as total, 'comment n' as comment
from table_A
Where 
    requirement1 = 1
    and requirement2 = 100
    and requirement3 = 'A'
    and requirement4 = 50
    .
    .
    .
    requirementn = 5

编辑1:我要实现的目标

+------+-------------+-------+------------+
| step | totalAmount | total |  comment   |
+------+-------------+-------+------------+
| 1    |      10000  |    50 | comment 1  |
| 2    |        5000 |   100 | comment 2  |
| 3    |        2000 |   500 | comment 3  |
| .    |           . |     . | .          |
| .    |           . |     . | .          |
| .    |           . |     . | .          |
| n    |        5000 |    10 | comment n  |
+------+-------------+-------+------------+

编辑1:我如何解决问题

我已经到了可以使用局部变量将新需求添加到上一个需求的地步。但是,我无法弄清楚是否可以对已经存在SET的变量进行某种重新分配。因此,除了获取每个步骤的新名称之外,我只能获取步骤1的步骤计数和注释。我在出现问题的地方添加了注释。我的代码如下:

    -- general selection requirements
    DECLARE @selectedOverview varchar(1000)
    -- requirements step 1
    DECLARE @stepRequirement1 varchar(1000)
    DECLARE @step varchar(50)
    DECLARE @comment varchar(100)
    DECLARE @requirement1 varchar(1)
    DECLARE @requirement2 varchar(100)
    DECLARE @requirement3 varchar(100)
    SET @step = 1
    SET @comment = 'Total overview'
    SET @requirement1 = 1 
    SET @requirement2 = 100
    SET @requirement3 = 'A'
    -- additional requirements step 2
    DECLARE @stepRequirement2 varchar(1000)
    DECLARE @requirement4 varchar(100)
    SET @requirement4 = 50


    -- dynamic selection
    SET
        @selectedOverview = 
            'select 
                ' + @step + ' as step
                ,sum(totalamount) as beløb
                ,count(*) as antal
                ,' + '''' + @comment + '''' + ' as comment
            from KONVICI.dbo.A_MATRIX 
                where ' 

    -- step2
    SET 
    @stepRequirement1 = 
        @selectedOverview
        +
         'requirement1 = ' + @requirement1
        + 
        ' and requirement2 = ' + @requirement2  
        +
        ' and requirement3 = '  + '''' + @requirement3 + ''''
    EXEC(@stepRequirement3)
    -- step 2
    SET @comment = 'one layer has been removed' -- **PROBLEM: the re-assignment is not working**
    SET @step = @step + 1 -- **PROBLEM: @step is not incremented by 1**
    SET 
    @stepRequirement2 = 
        @stepRequirement1 
        + 
        ' and requirement4 = ' + @requirement4 
    EXEC(@stepRequirement2) .
.
.
-- step n goes here
-- the same approach as for step2

3 个答案:

答案 0 :(得分:2)

我的想法(并且事先对语法错误表示谅解,这个想法很清楚)是用一个case语句代替步骤来替换并集,这将简化事情,因为所有数据都来自同一表并且只是使用了计算步长值。

只要确保您使用某些布尔条件重叠的表达式即可。

例如

select 
    case 
        when requirement1 = 1 and requirement2 = 100 and requirement3 = 'A' and requirement4 = 50 then 2
        when requirement1 = 1 and requirement2 = 100 and requirement3 = 'A' then 1
        ...
        ...
    end as step,
    sum(Amount) as totalValue, count(*) as total, 'comment 1' as comment

答案 1 :(得分:1)

您可以通过CTE简化一点

WITH CTE as (
SELECT sum(Amount) as totalValue, count(*) as total
from table_A
)

SELECT 1, comment = 'comment 1', * FROM CTE 
WHERE     requirement1 = 1
    and requirement2 = 100
    and requirement3 = 'A'

UNION ALL

SELECT 2, comment = 'comment 2', * FROM CTE    
    where requirement1 = 2
    and requirement2 = 100
    and requirement3 = 'A'
    and requirement4 = 50
...

没有动态SQL。

答案 2 :(得分:0)

一种非常简单的方法是使用临时表,然后添加累积的其他WHERE语句。这还增加了能够查看满足每个步骤标准的所有观察结果的好处。代码可能看起来像这样:

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

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

-- select data step 2
select * 
into #table_step2
from #table_step1
where 
    requirement4 = 50
...

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

UNION ALL

select 2 as step, sum(Amount) as totalValue, count(*) as total, 'comment 2' as comment

UNION ALL
...