2016-02-26 72 views
1

可以说我有这个测试表:返回匹配列我在哪里

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具有8的列。

的结果应该是:

AdrNr Nr3 
500 8 
+0

'UNPIVOT'使列行和'SELECT ... WHERE'。或结合整个条件,如'Nr1 = 8或Nr2 = 8或...'。没有你演示的这种语法。 –

回答

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 

我的价值观后:Is UNPIVOT the best way for converting columns into rows?

UPDATE(动态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 
+0

感谢您的帮助,但输出不是我想要的。它必须是AdrNr 500 Nr3 8 – user2210516

+0

请告诉,如果'(501,3, - > 8,8, - <42,5,76,91)'有多个值被清除了怎么办? – Devart

+0

@ user2210516请检查更新;) – Devart

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 
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) 
+2

如果有多个带有“8”的记录,那么这个SQL只会将“@ sql”设置为最后一个找到的。结果集将只包含一行。 –

+0

是的詹姆斯对不起,我错过了这一点。如果没有匹配的行,我的将是一个错误。我的坏 – mindbdev