2016-02-26 69 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