2014-12-04 34 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