【问题标题】:Struggling on the easiest way to dynamically select/join values from a table努力寻找从表中动态选择/连接值的最简单方法
【发布时间】:2016-04-14 07:28:12
【问题描述】:

我有一个变量和值表,我将知道要选择哪些参数代码。该表将动态更改。

CREATE TABLE #TreatmentTableVariables (ParameterCode VARCHAR(64), Value varchar(64))
INSERT #TreatmentTableVariables  VALUES ('TripOriginLocationCode','BGY')

然后我有另一个名为 AnalyticsDW.Treatment 的表,其中有一个名为 TripOriginLocationCode 的列,我想从 AnalyticsDW.Treatment 中选择那些行,其中 TripOriginLocationCode = #TreatmentTableVariables 中的值。

AnalyticsDW.Treatment 的主键为 TreatmentID。

所以我最初是使用动态 SQL 来选择临时表中包含的 TreatmentID 的列

SELECT @Columns = SubString (  (  SELECT + ', ' +'t.' + QUOTENAME(Column_name)
from INFORMATION_SCHEMA.columns c
JOIN #TreatmentTableVariables  t ON c.COLUMN_NAME=t.ParameterCode
WHERE Table_name IN ('Treatment','TreatmentProduct') AND TABLE_SCHEMA='AnalyticsDW'
FOR XML PATH ( '' ) ), 1, 1000) 

但我正在努力解决如何仅选择 AnalyticsDW.Treatment 的行,其中动态列等于 #TreatmentTableVariables 中的参数代码,而 #TreatmentTableVariables 中的值等于该特定列的观察值。

AnalyticsDW.Treatment 数据示例:

Declare  AnalyticsDW.Treatment table
(
TreatmentID varchar(100),
TripOriginLocationCode varchar(100),
TripDestinationLocationCode varchar(100)
)

insert into AnalyticsDW.Treatment values
('1','BRG','SLC'),
('2','AHO','BRG')

目标数据集:

Declare  @goal table
(
TripOriginLocationCode varchar(100)
)

insert into @goal values
('BRG')

关于我如何从目标数据集中进行选择的示例(在动态 sql 查询中):

declare @dynamicquery varchar(200)

set @dynamicquery='
select a.*, '+@Columns+' into #CompletePricingtypes2 from #somedataset a 
join AnalyticsDW.Treatment t on a.TreatmentID=t.TreatmentID '

编辑:附加信息

declare
@whereConditions nvarchar(max) = stuff((
    -- here we create where conditions as
    --   paramCode in (itsValues) 
    --   or anotherParamCode in (anotherItsValues) etc.
    select
        'or ' + 'where ' +'t.' +ParameterCode + ' in ('+''''+ltrim([Values]) +''''+') '
    from (
        -- here we create output with two columns: parameter code and
        -- all values associated with that code separated by comma
        select
            t.ParameterCode,
            stuff((
                select
                    ', ' + [Value]
                from #TreatmentTableVariables
                where
                    ParameterCode in (t.ParameterCode)

                FOR XML PATH ('')
            ), 1, 1, '') as [Values]
        from #TreatmentTableVariables t
        where ParameterCode in (select COLUMN_name from INFORMATION_SCHEMA.columns where  Table_name IN ('Treatment') AND TABLE_SCHEMA='AnalyticsDW')
    ) conditions
), 1, 3, '')
print @whereconditions

编辑:这行得通

 select
    'or ' +   ParameterCode + ' in('+ [Values] +')
       '

    from (
 select distinct
            t.ParameterCode,

           (
                select
                    ', ''' + [Value] + ''''
                from #TreatmentTableVariables
                where
                    ParameterCode in (t.ParameterCode)

            ) as [Values]

        from #TreatmentTableVariables t
        where ParameterCode in (select 
                                COLUMN_name 
                                from INFORMATION_SCHEMA.columns
                                where  Table_name IN ('Treatment') AND TABLE_SCHEMA='AnalyticsDW')
        ) conditions 

【问题讨论】:

    标签: sql-server dynamic-sql


    【解决方案1】:

    UPD。首先,我忘记了内部选择中的不同。

    其次,您仍在尝试用单引号包裹整个 in 条件。你需要

    or ParameterCode in ('value1', 'value2', 'value3')
    

    ,但你这样做是

    or ParameterCode in ('value1, value2, value3') -- look at quotes
    

    第三,你把where 放到每个or 条件上

    where ParameterCode1 in (...)
    or where ParameterCode2 in (...)
    or where ParameterCode3 in (...)
    

    @whereCondition 字符串构造中删除它并完成您的查询,就像我在@selectQuery 变量中所做的那样。


    我认为您可以使用真正的动态 sql 查询,即动态构建查询然后执行它(查看下面代码 sn-p 中的 cmets 了解更多信息):

    declare
        @whereConditions nvarchar(max) = stuff((
        -- here we create where conditions as
        --   paramCode in (itsValues) 
        --   or anotherParamCode in (anotherItsValues) etc.
        select
            'or ' + ParameterCode + ' in (' + [Values] + ') 
            '
        from (
            -- here we create output with two columns: parameter code and
            -- all values associated with that code separated by comma
            select distinct
                t.ParameterCode,
                stuff((
                    select
                        ', ''' + [Value] + ''''
                    from #TreatmentTableVariables
                    where
                        ParameterCode in (t.ParameterCode)
                    FOR XML PATH ('')
                ), 1, 1, '') as [Values]
            from #TreatmentTableVariables t
            where ParameterCode in (
                select 
                    COLUMN_name 
                from INFORMATION_SCHEMA.columns 
                where
                    table_name = 'Treatment'
                    and table_schema ='AnalyticsDW'
            )
        ) conditions
        FOR XML PATH ('') -- !!! this one
    ), 1, 3, '')
    
    declare
        @selectQuery nvarchar(max) = N'
    select
        *
    from AnalyticsDW.Treatment
    where
        ' + @whereConditions
    
    print @selectQuery
    exec sp_executesql @selectQuery
    

    【讨论】:

    • 很好,至少作为一个基础工作得很好。谢谢。一个问题,在 select 'or ' + ParameterCode + ' in (' + [Values] + ') ' 我怎么能调整它,使值有引号?我一直在尝试调整它,但主要是 [Values] 作为字符串而不是引号内的 [Value]。
    • @AdamSanders,不客气!查看更新的查询版本。您需要用引号将每个 [Value] 括起来,即在内部选择中进行。如您所见,我在[Value] 之前和之后添加了'(必须将其转义,因此它会加倍为'')。
    • 知道了,还有一个问题。当从#TreatmentTableVariables 中提取多个参数代码时,我不确定要调整什么。如果有一个值我让它工作,但如果我添加另一个值,它会说“子查询返回超过 1 个值。当子查询遵循 =、!=、、>= 或当子查询用作表达式。”
    • 更新了我的查询并在帖子中添加了说明
    • 我明白你在说什么,但由于某种原因,使用新代码仍然给我同样的错误。
    猜你喜欢
    • 1970-01-01
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2019-06-26
    相关资源
    最近更新 更多