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 给定角色的列名(最好在合并数组中)?
例如:
- 对于角色 a,return
column_1
和 column_2
- 对于角色 b,return
column_1
和 column_3
- 对于角色 c,return
column_2
和 column_3
我认为你让这件事变得比需要的更难了。在您的子查询中,您将字符串文字与总是会失败的 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
我有一个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 给定角色的列名(最好在合并数组中)?
例如:
- 对于角色 a,return
column_1
和column_2
- 对于角色 b,return
column_1
和column_3
- 对于角色 c,return
column_2
和column_3
我认为你让这件事变得比需要的更难了。在您的子查询中,您将字符串文字与总是会失败的 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