0

入力されていないフィールドのリストを一時テーブルからコンマ区切りのステートメントに取得しようとしている状況があります。

したがって、例のデータ (常に単一の行であり、おそらく一時テーブルにあります (実際のデータは多数のソース テーブルから取得されるため)):

Field1     Field2   Field3   Field4
'aaa'      null      ''      null

そして、のマッピングテーブル

FieldName    Question   Section
'Field1'     'Q1'       'Sec1'
'Field2'     'Q2'       'Sec1'
'Field3'     'Q3'       'Sec2'
'Field4'     'Q4'       'Sec2'

次の結果が欲しいです。

Section   UnansweredQs
'Sec1'    'Q2'
'Sec2'    'Q3, Q4'

次のようにして、カンマ区切りの質問リストまで取得しました。

create table #testData (f1 varchar(50), f2 int, f3 varchar(50), f4 varchar(50))
create table #qlist (fieldName varchar(5), question varchar(3), section varchar(5))

insert into #qlist values ('f1', 'q1', 'sec1'), ('f2', 'q2', 'sec1'), ('f3', 'q3', 'sec2'), ('f4', 'q4', 'sec2')

insert into #testData values ('asda', null, '', null)

それで

declare @usql nvarchar(max) = ''
declare @sql nvarchar(max)
declare @xml xml

--build a gargantuan set of union statements, comparing the column value to null/'' and putting q# if it is
set @usql = 
    (
    select 'select case when ' + c.name + ' is null or ' + c.Name + ' = '''' then ''' + q.question + ', '' else '''' end from #testData union '
    from tempdb..syscolumns c
    inner join #qlist q
        on c.name = q.fieldName
    where c.id = object_id('tempdb..#testData') 
    for xml path('')
    );
--remove the last 'union', append for xml path to pivot the rows into a single column of concatenated rows
set @usql = left(@usql, len(@usql) - 6) + ' for xml path('''')'

print @usql

--remove final comma
--get the position of the last comma in the select statment (ie after the final unanswered question)
declare @lastComma int = charindex(',', reverse(@usql))
--add the bit before the last comma, and the bit after the last comma but skip the actual comma :)
set @usql = left(@usql, len(@usql) - @lastComma) + right(@usql, @lastComma - 2)

exec (@usql)

これで私は得る

XML_F52E2B61-18A1-11d1-B105-00805F49916B
----------------------------------------
q2, q3, q4

しかし、その結果セットを別のテーブルまたは変数に (insert into #tmpresult exec (@usql)アプローチを介して) 取得することはできません。

通常、Msg 1086, Level 15, State 1, Line 1 The FOR XML clause is invalid in views, inline functions, derived tables, and subqueries when they contain a set operator. To work around, wrap the SELECT containing a set operator using derived table syntax and apply FOR XML on top of it.エラーが発生します。

ラッピング、ユニオンの削除、CTEなど、さまざまなことを試しましたが、機能しません。

4

2 に答える 2

1

質問があります:

with cte as (
    select
        N.Name
    from Table1
        cross apply (values
           ('Field1', Field1),
           ('Field2', Field2),
           ('Field3', Field3),
           ('Field4', Field4)
        ) as N(Name,Value)
    where N.Value is null or N.Value = ''
)
select distinct
    T2.Section,
    stuff(
        (
            select ', ' + TT.Question
            from Table2 as TT
                inner join cte as c on c.Name = TT.FieldName
            where TT.Section = T2.Section
            for xml path(''), type
        ).value('.', 'nvarchar(max)')
    , 1, 2, '') as UnansweredQs
from Table2 as T2

自分で動的に変えることができます:)

SQL フィドルのデモ

于 2013-08-16T12:50:14.780 に答える