返回与我的Where匹配的列

时间:2016-02-26 08:39:57

标签: sql sql-server tsql

让我说我有这个测试表:

CREATE TABLE Test (AdrNr INT, Nr1 INT, Nr2 INT, Nr3 INT, Nr4 INT, Nr5 INT, Nr6 INT, Nr7 INT)

INSERT INTO @t
VALUES (500, 3, 4, 8, 42, 5, 76, 91)

现在我想知道Nr1..Nr7列中是否有8个:

SELECT *
FROM Test
WHERE 8 IN (Nr1, Nr2, Nr3, Nr4, Nr5, Nr6, Nr7);

这样运作正常,但我的问题是,是否可以获取AdrNr,然后只能获得Nr1Nr7的{​​{1}}列。

结果应该是:

8

3 个答案:

答案 0 :(得分:6)

DECLARE @t TABLE (AdrNr INT, Nr1 INT, Nr2 INT, Nr3 INT, Nr4 INT, Nr5 INT, Nr6 INT, Nr7 INT)

INSERT INTO @t
VALUES (500, 3, 4, 8, 42, 5, 76, 91)

SELECT AdrNr, a
FROM @t
CROSS APPLY (
    VALUES
        ('Nr1', Nr1),
        ('Nr2', Nr2),
        ('Nr3', Nr3),
        ('Nr4', Nr4),
        ('Nr5', Nr5),
        ('Nr6', Nr6),
        ('Nr7', Nr7)
) t(a, b)
WHERE b = 8

输出 -

AdrNr       a   
----------- ----
500         Nr3 

关于VALUES的帖子:Is UNPIVOT the best way for converting columns into rows?

更新(动态SQL):

DECLARE @t TABLE (AdrNr INT, Nr1 INT, Nr2 INT, Nr3 INT, Nr4 INT, Nr5 INT, Nr6 INT, Nr7 INT)

INSERT INTO @t
VALUES
    (500, 3, 4, 8, 42, 5, 76, 91),
    (501, 3, 8, 8, 42, 5, 76, 91)

IF OBJECT_ID('tempdb.dbo.#tbl') IS NOT NULL
    DROP TABLE #tbl

SELECT AdrNr, t.col, t.val
INTO #tbl
FROM @t
CROSS APPLY (
    VALUES
        ('Nr1', Nr1), ('Nr2', Nr2), ('Nr3', Nr3), ('Nr4', Nr4),
        ('Nr5', Nr5), ('Nr6', Nr6), ('Nr7', Nr7)
) t(col, val)
WHERE val = 8

DECLARE @SQL NVARCHAR(MAX)
SET @SQL = '
SELECT *
FROM #tbl
PIVOT (
    MAX(val)
    FOR col IN (' + STUFF((
    SELECT DISTINCT ', [' +  col + ']'
    FROM #tbl
    FOR XML PATH('')), 1, 2, '') + ') 
) p'

EXEC sys.sp_executesql @SQL

输出 -

AdrNr       Nr2         Nr3
----------- ----------- ---------
500         NULL        8
501         8           8

答案 1 :(得分:2)

这将产生您想要的输出:

DECLARE @t TABLE (AdrNr INT, Nr1 INT, Nr2 INT, Nr3 INT, Nr4 INT, Nr5 INT, Nr6 INT, Nr7 INT)

INSERT INTO @t VALUES (500, 3, 4, 8, 42, 5, 76, 91)
INSERT INTO @t VALUES (600, 3, 8, 9, 42, 5, 76, 91)

select AdrNr
      ,case when Nr1 = 8 then 8 else null end as Nr1
      ,case when Nr2 = 8 then 8 else null end as Nr2
      ,case when Nr3 = 8 then 8 else null end as Nr3
      ,case when Nr4 = 8 then 8 else null end as Nr4
      ,case when Nr5 = 8 then 8 else null end as Nr5
      ,case when Nr6 = 8 then 8 else null end as Nr6
      ,case when Nr7 = 8 then 8 else null end as Nr7
into   #temp
from   @t
where  8 IN (Nr1, Nr2, Nr3, Nr4, Nr5, Nr6, Nr7)

if not exists (select 1 from #temp where Nr1 = 8) alter table #temp drop column nr1
if not exists (select 1 from #temp where Nr2 = 8) alter table #temp drop column nr2
if not exists (select 1 from #temp where Nr3 = 8) alter table #temp drop column nr3
if not exists (select 1 from #temp where Nr4 = 8) alter table #temp drop column nr4
if not exists (select 1 from #temp where Nr5 = 8) alter table #temp drop column nr5
if not exists (select 1 from #temp where Nr6 = 8) alter table #temp drop column nr6
if not exists (select 1 from #temp where Nr7 = 8) alter table #temp drop column nr7

select *
from   #temp

drop table #temp

输出:

AdrNr       Nr2         Nr3
----------- ----------- -----------
500         NULL        8
600         8           NULL

答案 2 :(得分:1)

您可以使用动态查询

来实现
DECLARE @SQL VARCHAR(500)

SELECT
    @SQL = 'SELECT ' + CONVERT(VARCHAR, AdrNr) + ' AS AdrNr, 8 AS ' + 
    CASE
        WHEN Nr1 = 8 THEN 'Nr1'
        WHEN Nr2 = 8 THEN 'Nr2'
        WHEN Nr3 = 8 THEN 'Nr3'
        WHEN Nr4 = 8 THEN 'Nr4'
        WHEN Nr5 = 8 THEN 'Nr5'
        WHEN Nr6 = 8 THEN 'Nr6'
        WHEN Nr7 = 8 THEN 'Nr7'
    END
FROM Test
WHERE 8 IN (Nr1, Nr2, Nr3, Nr4, Nr5, Nr6, Nr7)

EXEC (@SQL)