2014-12-04 46 views
3

我希望有人有一个快速的建议/解决以下,基于以下示例表:的SQL Server:根据记录的价值回归列名

|Field1 |Field2 |Field3 |Field4 | 
|-------|-------|-------|-------| 
| 1  | 0  | 0  | 1  | 

我希望能够构建一个查询以返回其值(基于单个记录)= 1的列名。这不依赖于游标或临时表。

I.e.我想下面的输出:

Field1 
Field4 

我一直在努力做各种地加入反对sys.columns(和sys.tables),但至今收效甚微。

回答

5

您还可以使用Cross apply

SELECT Cname 
FROM Tablename 
     CROSS apply (VALUES('Field1',Field1), 
          ('Field2',Field2), 
          ('Field3',Field3), 
          ('Field4',Field4)) ca (cname, data) 
WHERE data = 1 

要工作动态使用。

CREATE TABLE test 
    (
    Field1 INT, 
    Field2 INT, 
    Field3 INT, 
    Field4 INT 
) 

INSERT INTO test 
VALUES  (1,0,0,1) 

DECLARE @collist VARCHAR(max)='', 
     @sql  NVARCHAR(max) 

SELECT @collist += '(''' + COLUMN_NAME + ''',' + COLUMN_NAME + '),' 
FROM INFORMATION_SCHEMA.columns 
WHERE TABLE_NAME = 'test' 
     AND COLUMN_NAME LIKE 'Field%' 
     AND TABLE_SCHEMA = 'dbo' 

SELECT @collist = LEFT(@collist, Len(@collist) - 1) 

SET @sql =' 
SELECT Cname 
FROM test 
     CROSS apply (VALUES' + @collist 
      + ') ca (cname, data) 
WHERE data = 1 ' 

EXEC Sp_executesql 
    @sql 
2

你可以做到这一点使用union all,例如:

select 'Field1' from table t where Field1 = 1 union all 
select 'Field2' from table t where Field2 = 1 union all 
select 'Field3' from table t where Field3 = 1 union all 
select 'Field4' from table t where Field4 = 1; 
+0

这肯定会工作,我感谢您的建议,但我忘了提,我也需要动态地做到这一点对基于给定的标准表。例如。我应该想要查询我选择的表并返回名称以'Field'('Field%')开始并且其值= 1的所有列名称。 – 2014-12-04 03:15:38

+0

+ One。也许'UNION'会比'UNION ALL'更好,如果OP不希望'Field1'无休止地重复匹配'Field1 = 1'的无尽行。即*列是否在任何行中包含1 *。 – 2014-12-04 03:18:31

+0

@ ta.speot.is。 。 。该OP特别提到该值基于单一记录。逻辑中需要一个'和recordnum = xxx'。 – 2014-12-04 03:30:46