Return 索引为真时的列名数组(SQL Server 2008)

Return Array of Column Names if Index is True (SQL Server 2008)

我有一个SQL服务器table,格式如下(数据类型为Bit):

role  |  column_1  |  column_2  |  column_3
------+------------+------------+-----------
a     |  True      |  True      |  False
b     |  True      |  False     |  True
c     |  False     |  False     |  True

我尝试了以下方法:

SELECT *
FROM Roles
WHERE EXISTS (SELECT 'column_1' = 1)
             (SELECT 'column_2' = 1)
             (SELECT 'column_3' = 1)

然而,这似乎 return 值 3 次。

如果索引为真,我如何 return 给定角色的列名(最好在合并数组中)?

例如:

我认为你让这件事变得比需要的更难了。在您的子查询中,您将字符串文字与总是会失败的 int 进行比较。很确定你只需要在这里使用几个谓词。

SELECT *
FROM Roles
WHERE column_1 = 1
    AND column_2 = 1
    AND column_3 = 1

根据您的评论。

简单方法 如果您不介意列出字段

Select Role
      ,Roles = stuff(
               replicate(',column_1',column_1)
              +replicate(',column_2',column_2)
              +replicate(',column_3',column_3)
              ,1,1,'')
 From  Roles

或者如果您想要更动态的方法

例子

Select A.Role
      ,C.*
 From Roles A
 Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
 Cross Apply (
               Select Roles = Stuff((Select ','+Field 
                                       From (
                                                Select Field = a.value('local-name(.)','varchar(100)')
                                                      ,Value = a.value('.','varchar(max)') 
                                                 From  B.XMLData.nodes('/row')  as C1(n)
                                                 Cross Apply C1.n.nodes('./@*') as C2(a)
                                                 Where a.value('local-name(.)','varchar(100)') not in ('role','ExcludeOther')
                                                   and a.value('.','varchar(max)') ='1'
                                            ) C1
                                       For XML Path ('')),1,1,'') 
             ) C

两者都会Return

Role    Roles
a       column_1,column_2
b       column_1,column_3
c       column_3

基于 John Cappelletti 建议的存储过程。

输入table名称、列名、过滤器

Returns 过滤索引 |列名 |列值

-- filterTableWithString
Alter Procedure [dbo].[filterTableWithString] 
@table as VarChar(50),
@column as VarChar(50),
@filter as VarChar(50),
@string as VarChar(max)

As

Declare @ssql NVarChar(max)

Select @ssql = 
'Select ' + @column +', c.*

  From' + QUOTENAME(@table) + 'a 
  Cross Apply (Values (Cast((Select A.* for XML RAW) as xml))) B(XMLData)
  Cross Apply (
    Select Field = a.value(''local-name(.)'',''VarChar(max)''), 
    Value = a.value(''.'',''VarChar(max)'') 
    From  B.XMLData.nodes(''/row'')  as C1(n)
    Cross Apply C1.n.nodes(''./@*'') as C2(a)
    Where a.value(''local-name(.)'',''VarChar(max)'') Not In (''ExcludeOther'')
  ) C
Where ' + @column + ' = ''' + @filter + ''' 
And Cast(c.value as VarChar(max)) Like ( ''' + @string +''')'

Exec sp_executesql @ssql

正如所承诺的,这是我的 "dynamic" EAV 函数。您可以传递一条记录或整个 table(避免大 tables)。

需要说明的是,这是一个辅助函数,用于 "dynamically" 反转较小的 table 或交叉应用中的选定记录。

请注意,查询中的第一个字段必须是您的实体。

Table

的例子
Declare @User table (ID int,Active bit,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50))
Insert into @User values
(1,1,'John','Smith','john.smith@email.com'),
(2,0,'Jane','Doe'  ,'jane.doe@email.com')

Select * From [dbo].[tvf-EAV]((Select * From @User for XML RAW))

Returns

Entity  Attribute   Value
1       Active      1
1       First_Name  John
1       Last_Name   Smith
1       EMail       john.smith@email.com
2       Active      0
2       First_Name  Jane
2       Last_Name   Doe
2       EMail       jane.doe@email.com

通过交叉应用的 ROW 示例

Declare @User table (ID int,Active bit,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50))
Insert into @User values
(1,1,'John','Smith','john.smith@email.com'),
(2,0,'Jane','Doe'  ,'jane.doe@email.com')

Select A.EMail
      ,B.* 
 From  @User A
 Cross Apply [dbo].[tvf-EAV]((Select A.* for XML RAW)) B
 Where Active=1

Returns

EMail                   Entity  Attribute   Value
john.smith@email.com    1       Active      1
john.smith@email.com    1       First_Name  John
john.smith@email.com    1       Last_Name   Smith
john.smith@email.com    1       EMail       john.smith@email.com