我希望你一切都好。 对于我想自动化的重复性任务,我需要您的帮助和建议。 经理每月都会要求我根据相同的表和列运行一系列SQL查询。 我以为我可以创建一个规则表,让他创建自己的查询 所以我创建了这样的规则表:
基于此表,我想连续执行3个查询。
第一个查询是针对规则“ + NET 3或更多”的,查询如下:
SELECT * FROM Table Where
([QuestionCode] = 'HSZ' AND ResponseCode = 3)
OR ([QuestionCode] = 'HSZ' AND ResponseCode = 4)
第二个查询用于“年龄在25-35之间的年龄”规则,查询如下:
SELECT * FROM Table Where
([QuestionCode] = 'RS2' AND ResponseCode >= 25)
AND ([QuestionCode] = 'RS2' AND ResponseCode < 35)
第三个查询用于规则“ CHN”和“ HSZ”,查询如下:
SELECT * FROM Table Where
([QuestionCode] = 'CHN' AND ResponseCode = 5)
AND ([QuestionCode] = 'HSZ' AND ResponseCode = 1)
我希望您对此解决方案有意见,尤其是对创建此动态查询有帮助 这是创建规则表的脚本:
WITH CTE AS
(
SELECT RuleId = 1
, NetQuestionCode = '+NET 3 or More'
, QuestionCategory = 'HSZ'
, QuestionCode = 'HSZ'
, ResponseOperator = '='
, ResponseCode = '3'
, RuleOrder = '1'
, CategoryRule = 'OR'
UNION ALL
SELECT RuleId = 1
, NetQuestionCode = '+NET 3 or More'
, QuestionCategory = 'HSZ'
, QuestionCode = 'HSZ'
,ResponseOperator = '='
, ResponseCode = '4'
, RuleOrder = '2'
, CategoryRule = 'OR'
UNION ALL
SELECT RuleId = 2
, NetQuestionCode = 'Age Between 25-35'
, QuestionCategory = 'RS2'
, QuestionCode = 'RS2'
,ResponseOperator = '>='
, ResponseCode = '25'
, RuleOrder = '1'
, CategoryRule = 'and'
UNION ALL
SELECT RuleId = 2
, NetQuestionCode = 'Age Between 25-35'
, QuestionCategory = 'RS2'
, QuestionCode = 'RS2'
,ResponseOperator = '<'
, ResponseCode = '35'
, RuleOrder = '2'
, CategoryRule = 'and'
UNION ALL
SELECT RuleId = 3
, NetQuestionCode = 'CHN AND HSZ'
, QuestionCategory = 'CHN'
, QuestionCode = 'CHN'
,ResponseOperator = '='
, ResponseCode = '5'
, RuleOrder = '1'
, CategoryRule = 'and'
UNION ALL
SELECT RuleId = 3
, NetQuestionCode = 'CHN AND HSZ'
, QuestionCategory = 'CHN'
, QuestionCode = 'HSZ'
,ResponseOperator = '='
, ResponseCode = '1'
, RuleOrder = '2'
, CategoryRule = 'and'
)
SELECT *
Into [dbo].[Rules_Parameters]
FROM CTE
谢谢您的帮助。
答案 0 :(得分:0)
尝试一下,我基于您的CTE,添加了更多常见的表表达式,以构建WHERE的动态部分,然后使用另一个表达式根据运算符对同一规则的条件进行分组,最后将其移动到将与动态sql一起使用的变量。
declare @DynamicQuery nvarchar(max)=''
; WITH CTE AS
(
SELECT RuleId = 1
, NetQuestionCode = '+NET 3 or More'
, QuestionCategory = 'HSZ'
, QuestionCode = 'HSZ'
, ResponseOperator = '='
, ResponseCode = '3'
, RuleOrder = '1'
, CategoryRule = 'OR'
UNION ALL
SELECT RuleId = 1
, NetQuestionCode = '+NET 3 or More'
, QuestionCategory = 'HSZ'
, QuestionCode = 'HSZ'
,ResponseOperator = '='
, ResponseCode = '4'
, RuleOrder = '2'
, CategoryRule = 'OR'
UNION ALL
SELECT RuleId = 2
, NetQuestionCode = 'Age Between 25-35'
, QuestionCategory = 'RS2'
, QuestionCode = 'RS2'
,ResponseOperator = '>='
, ResponseCode = '25'
, RuleOrder = '1'
, CategoryRule = 'and'
UNION ALL
SELECT RuleId = 2
, NetQuestionCode = 'Age Between 25-35'
, QuestionCategory = 'RS2'
, QuestionCode = 'RS2'
,ResponseOperator = '<'
, ResponseCode = '35'
, RuleOrder = '2'
, CategoryRule = 'and'
UNION ALL
SELECT RuleId = 3
, NetQuestionCode = 'CHN AND HSZ'
, QuestionCategory = 'CHN'
, QuestionCode = 'CHN'
,ResponseOperator = '='
, ResponseCode = '5'
, RuleOrder = '1'
, CategoryRule = 'and'
UNION ALL
SELECT RuleId = 3
, NetQuestionCode = 'CHN AND HSZ'
, QuestionCategory = 'CHN'
, QuestionCode = 'HSZ'
,ResponseOperator = '='
, ResponseCode = '1'
, RuleOrder = '2'
, CategoryRule = 'and'
),WhereCondition as (
SELECT *,'([QuestionCode] = '''+QuestionCode+''' AND ResponseCode '+ResponseOperator+' '+ResponseCode+')' [Condition] FROM CTE
),G as (
select *,cast(Condition as varchar(max)) WhereAll from WhereCondition where RuleOrder=1
union all
select c.*,WhereAll+' '+c.CategoryRule+' '+c.Condition from G
inner join WhereCondition c on c.RuleOrder=(G.RuleOrder+1) and c.RuleId=G.RuleId
),qq as (
select top(3) 'SELECT * FROM Table Where '+WhereAll+';' [q] from G order by RuleOrder desc
)
select @DynamicQuery=@DynamicQuery+q from qq
EXECUTE sp_executesql @DynamicQuery
或者如果您想从[Rules_Parameters]中进行更改,则更改如下:-
;with WhereCondition as (
SELECT *,'([QuestionCode] = '''+QuestionCode+''' AND ResponseCode '+ResponseOperator+' '+ResponseCode+')' [Condition] FROM [dbo].[Rules_Parameters]
),G as (
select *,cast(Condition as varchar(max)) WhereAll from WhereCondition where RuleOrder=1
union all
select c.*,WhereAll+' '+c.CategoryRule+' '+c.Condition from G
inner join WhereCondition c on c.RuleOrder=(G.RuleOrder+1) and c.RuleId=G.RuleId
),qq as (
select top(3) 'SELECT * FROM Table Where '+WhereAll+';' [q] from G order by RuleOrder desc
)
select @DynamicQuery=@DynamicQuery+q from qq
EXECUTE sp_executesql @DynamicQuery
无论哪种方式,@ DynamicQuery变量都将包含以下内容:-
SELECT * FROM Table Where ([QuestionCode] = 'CHN' AND ResponseCode = 5) and ([QuestionCode] = 'HSZ' AND ResponseCode = 1);SELECT * FROM Table Where ([QuestionCode] = 'RS2' AND ResponseCode >= 25) and ([QuestionCode] = 'RS2' AND ResponseCode < 35);SELECT * FROM Table Where ([QuestionCode] = 'HSZ' AND ResponseCode = 3) OR ([QuestionCode] = 'HSZ' AND ResponseCode = 4);
希望这就是您想要的。
注意:我没有进行任何验证,例如ResponseOperator可能具有无法运行的操作符并中断了查询等。
注意:我没有使用STRING_AGG,因为您没有提到您的sql数据库版本。