选择所有具有特定值的列

时间:2020-03-17 13:32:55

标签: sql sql-server

我有一个表,其中包含大约200个不同的布尔列。这些基本上是On / Off开关,用于将另一个应用程序中的数据列入黑名单。在所述应用程序中,它还具有用于不同功能的多行。

您可以想象,当您必须根据某些excel工作表手动对其进行检查时,要对某个功能的“打开”列保持良好的概览是很累的,所以我想通过只显示来简化我的生活启用/设置为true的列。

类似的东西:

select [columns with value '1'] 
from table
where function = 'function1'

此表的位置:

+-----------+------+------+------+------+------+ | function | Col1 | Col2 | Col3 | Col4 | Col5 | +-----------+------+------+------+------+------+ | function1 | 1 | 0 | 1 | 1 | 0 | | function2 | 0 | 1 | 0 | 0 | 0 | +-----------+------+------+------+------+------+

返回此:

+----------+------+-------+-----+ | function | Col1 | Col3 | Col4 | +-----------+------+------+------+ | function1 | 1 | 1 | 1 | +-----------+------+------+------+

有什么办法做这样的事情吗?

2 个答案:

答案 0 :(得分:1)

如注释中所述,结果列的定义与表数据无关,但是以下方法可以将列名称返回为单个列,这是一种可能的解决方案:

表格:

CREATE TABLE Data (
    [Function] varchar(3),
    Col1 bit,
    Col2 bit,
    Col3 bit,
    Col4 bit,
    Col5 bit
)
INSERT INTO Data ([Function], Col1, Col2, Col3, Col4, Col5)
VALUES ('xyz', 1, 0, 1, 1, 1), ('abc', 0, 0, 0, 0, 1)

动态声明:

DECLARE @stm nvarchar(max) = N''

SELECT @stm = CONCAT(@stm, ',(','''', col.[name], ''', ',  col.[name], ')')
FROM sys.columns col
JOIN sys.tables tab ON col.object_id = tab.object_id
JOIN sys.schemas sch ON tab.schema_id = sch.schema_id
JOIN sys.types typ ON col.system_type_id = typ.system_type_id
WHERE 
    tab.[name] = 'Data' AND 
    sch.[name] = 'dbo' AND 
    col.[name] != 'Function'
ORDER By col.[name]

SELECT @stm = CONCAT(
    'SELECT d.[Function], STRING_AGG(v.ColName, '','') AS [Columns] FROM Data d CROSS APPLY (VALUES ',
    STUFF(@stm, 1, 1, ''),
    ') v(ColName, ColVal) WHERE v.ColVal = 1 GROUP BY d.[Function]'
)

PRINT @stm
EXEC sp_executesql @stm

结果:

Function    Columns
abc         Col5
xyz         Col1,Col3,Col4,Col5

答案 1 :(得分:0)

这是一个例子,我希望它会有所帮助,这有点棘手,但是如果您有任何疑问,请给我发送消息或评论,祝您好运。 >

IF OBJECT_ID('dbo.TestMr') IS NOT NULL DROP TABLE TestMr
IF OBJECT_ID('tempdb.dbo.#TestMrColumns') IS NOT NULL DROP TABLE #TestMrColumns
CREATE TABLE TestMr(x_function varchar(50),col1 numeric, col2 numeric, col3 numeric)
CREATE TABLE #TestMrColumns(y_function varchar(50),valor varchar(50),columna varchar(50))

--TEST VALUES
INSERT INTO TestMr VALUES('fun1',1,0,1)
INSERT INTO TestMr VALUES('fun2',0,1,0)


DECLARE  @script nvarchar(max)
DECLARE  @cols nvarchar(max)
--We get the columns from our table, this columns have to be of the same data_type or this wont work.
SET @cols = STUFF((SELECT  ',' + QUOTENAME(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TestMr' and DATA_TYPE='numeric' FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'),1,1,'')

--we make that columns rows to save them on a tempTable
set @script='select * from TestMr unpivot(valor for columna in ('+@cols+')) unpiv'
insert into #TestMrColumns exec (@script);

--we get the final columns for our select, here we can apply conditions for the columns that we want, in this case, we get
--the columns that had valor=1 and y_function=fun1/
SET @cols = STUFF((SELECT  ',' + QUOTENAME(columna) FROM #TestMrColumns where valor=1 and y_function='fun1' FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'),1,1,'')

--final select
set @script='select x_function,'+@cols+' from TestMr where x_function=''fun1'' '
exec(@script)