0

MS SQL Server に次のデータベース構造があります: ID、Col_A、Col_B、Col_C など...

ID を除く他のすべての列はブール型です。たとえば、Col_A = 1、Col_B = 0、Col_C = 1 とします。

列が 1 である列の名前を返す方法を探しています。この例では、戻り値は ID、Col_A、Col_C のようになります。

新しい列を追加したり古い列を削除したりするためにテーブルが頻繁に変更されるため、動的な数の列が存在します。

基本的に、次の投稿とまったく同じ機能が必要ですが、MS Sql Server クエリとして: 条件に一致する列名を選択する (MySQL)

SQL Fiddle リンクhttp://sqlfiddle.com/#!2/8f4ee/12は、MS SQL Server に実装したいものです。私はそれについてどのように考えていますか?CONCAT_WS と GROUP_CONCAT の 2 つの関数は、MS SQL Server によって認識されません。

どんな助けでも大歓迎です。

4

4 に答える 4

0

これを試して:

create table jtr (id varchar(36), col_a tinyint, col_b tinyint, col_c tinyint)
insert into jtr values (1, 1, 0, 1), (2, 0, 0, 1), (3, 1, 0 ,0), (4, 0, 1, 0)

CREATE TABLE #app (res tinyint)
CREATE TABLE #outmess (message varchar(1000))

DECLARE @dynsql varchar(1000)
DECLARE @colname sysname
DECLARE @mess varchar(1000)
DECLARE @id int

DECLARE #crs_tab INSENSITIVE CURSOR FOR
SELECT id FROM jtr
FOR READ ONLY

OPEN #crs_tab
FETCH NEXT FROM #crs_tab INTO @id

WHILE (@@FETCH_STATUS = 0)
BEGIN
    DECLARE #crs INSENSITIVE CURSOR FOR
    SELECT c.name FROM syscolumns c
    JOIN sysobjects o
    ON o.id = c.id
    WHERE o.name = 'jtr'
    AND o.xtype = 'U'
    AND c.type = 38
    FOR READ ONLY

    OPEN #crs
    FETCH NEXT FROM #crs INTO @colname
    WHILE (@@FETCH_STATUS = 0)
    BEGIN
        SET @dynsql = 'SELECT ' + @colname + ' FROM jtr where id = ' + CONVERT(varchar, @id)
        insert into #app
        exec (@dynsql)

        if (select res from #app) = 1
        begin
            if (@mess != '')
            begin
                set @mess = @mess + ', ' + @colname
            end
            else
            begin
                set @mess = @colname
            end
        end

        delete from #app
        FETCH NEXT FROM #crs INTO @colname
    END
    CLOSE #crs
    DEALLOCATE #crs
    insert into #outmess values (@mess)

    set @mess = ''
    FETCH NEXT FROM #crs_tab INTO @id
END
CLOSE #crs_tab
DEALLOCATE #crs_tab

select * from #outmess

これらのフィールドを持つサンプル テーブル JTR を作成しました。

そのテーブルに4行入れました。

そこで、2 つのカーソルを実装しました。1 つは JTR テーブルをスクロールするためのもので、もう 1 つは syscolumns からすべての列名をスクロールするためのものです。

ONEの値を持つすべての列について、列名でメッセージを作成します

一時テーブル #outmess には、カンマで連結された値が ONE のすべての列があります。

PS代わりにブール値を使用しましたtinyintを使用しました。syscolumns フィールド タイプでは、tinyint について 38 の値が付けられます

大丈夫か教えて

于 2013-07-19T22:09:49.750 に答える
0

考えられる解決策の 1 つは、さらに連結した動的 SQL アンピボット データです。

declare @stmt nvarchar(max)

select @stmt = IsNull(@stmt + ', ', '') + quotename(name)
from sys.columns
where object_id = object_id('TableName') and name != 'ID'
order by column_id

set @stmt = ';with du as (
    select *
    from TableName d
        unpivot (Val for Name in (' + @stmt + ')) u
)
select d.ID, IsNull(left(Cols, len(Cols) - 1), ''<None>'') as ColumnsSet
from (select ID from TableName) d
    cross apply (select (select Name + '', ''
        from du
        where Val = 1 and ID = d.ID
        for xml path ('''')) as Cols) c'

print @stmt
exec(@stmt)

次のようなデータの場合:

create table TableName (ID int, Col1 bit, Col2 bit, Col3 bit)
insert into TableName values
    (1, 0, 1, 1)
    ,(2, 1, 1, 1)
    ,(3, 1, 0, 0)
    ,(4, 0, 0, 0)

出力は次のとおりです。

ID          ColumnsSet
----------- -----------------
1           Col2, Col3
2           Col1, Col2, Col3
3           Col1
4           <None>
于 2013-07-19T22:48:15.390 に答える