在SQL中分配新的局部变量要求
我不熟悉在SQL中使用DECLARE、SET和EXEC(),所以我的方法可能不适合这个问题,所以请耐心听我说。我的目标是减少重复代码的使用。我现在有很多联合声明,其中where子句是累积的。部分代码如下所示(对于本文来说太长): 编辑1:初始代码在SQL中分配新的局部变量要求,sql,sql-server,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 requi
-- 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:我如何尝试解决问题
我已经到了可以使用局部变量将新需求添加到前一个需求的地步。但是,我无法确定是否有可能对已设置的变量进行某种重新赋值。因此,我只能获得步骤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
-- 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
...
你可以用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。您可以使用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。我的想法(请原谅语法错误,我的想法很清楚)是用case-when语句替换联合以获得步骤,这将简化事情,因为所有数据都来自同一个表,并且只用于计算步骤值
只要确保在某些布尔条件重叠时使用正确的表达式顺序即可
例如
我的想法(请原谅我的语法错误,这个想法很清楚)是用case-when语句替换联合以获得步骤,这将简化事情,因为所有数据都来自同一个表,只用于计算步骤值
只要确保在某些布尔条件重叠时使用正确的表达式顺序即可
例如
一种非常简单的方法是使用临时表,然后添加额外的WHERE语句。这还增加了能够看到满足每个步骤标准的所有观察结果的好处。代码可能如下所示:
-- 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
-- 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
...
一种非常简单的方法是使用临时表,然后添加额外的WHERE语句。这还增加了能够看到满足每个步骤标准的所有观察结果的好处。代码可能如下所示:
-- 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
-- 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
...
我不太理解这里的初始查询,但是,如果所有数据都来自同一个表(
table\u A
),为什么需要使用UNION
?为什么不在子句中的中使用或或类似的语句?(不知道什么是正确的,因为没有足够的细节。)此外,使用UNION-ALL
,可能会提高性能,因为每个数据集似乎已经是唯一的了;因此,检查不同的行只会浪费SQL Server的时间(尽管如果我们可以去掉UNION ALL
,那么这一点就没有意义了)。此外,字符串连接是一个非常糟糕的主意。SQL注入不是你的朋友。确保您的SQL参数化,或正确引用您的项目,例如使用QUOTENAME
。也许如果您可以显示一些示例输出并解释您想使用它做什么,我们可以找到更好的方法,似乎您在添加预期结果时忘了输入示例数据。是的,但是,正如我上面所评论的,您忘记了样本数据。如果没有原始数据,我们如何向您展示如何获得预期的结果集?我不太理解这里的初始查询,但是,如果所有数据都来自同一个表(table\u A
),为什么需要使用UNION
?为什么不在子句中的中使用或或类似的语句?(不知道什么是正确的,因为没有足够的细节。)此外,使用UNION-ALL
,可能会提高性能,因为每个数据集似乎已经是唯一的了;因此,检查不同的行只会浪费SQL Server的时间(尽管如果我们可以去掉UNION ALL
,那么这一点就没有意义了)。此外,字符串连接是一个非常糟糕的主意。SQL注入不是你的朋友。确保您的SQL参数化,或正确引用您的项目,例如使用QUOTENAME
。也许如果您可以显示一些示例输出并解释您想使用它做什么,我们可以找到更好的方法,似乎您在添加预期结果时忘了输入示例数据。是的,但是,正如我上面所评论的,您忘记了样本数据。如果没有原始数据,我们如何向您展示如何获得预期的结果集?或者更好的是,创建一个get_step()函数,该函数接受用于获取步骤的所有列,这将保留get step逻辑并简化维护。或者更好的是,创建一个get_step()函数,该函数接受用于获取步骤的所有列,这将保留获取步骤逻辑并简化维护。