2016-06-21 180 views
0

我有一個賦值給變量say @ var1 ='3,5,6,8'的值。我有一個表,其中有一些隨機數字組合的列,以逗號分隔。 PFB試樣臺查找與其他字符串匹配的字符串的一部分SQL

enter image description here

我所需要的表中的所有值除了ID 3,因爲它在其組合「3,9,8」具有9。

我想回復如下。

期望輸出應該只包含的ID 1,2和4.

原因是,任何/所有存在於@ var1的值的應存在於NOS和它不應該有一個沒有這是不出現在@ var1中。 Id 3是後者情況下的一個例子,其中包含9不屬於@ var1的部分。

我的輸出應該有標識1,2和4,而不是3

能否請您提出一些想法做呢?

+0

您應該將這4個值作爲不同的參數傳遞。如果你不這樣做,那麼在運行NOT LIKE –

+0

Pl之前,你需要分離出這些數據。很清楚你需要什麼!在第一行中,@ Var1有3,5,6和8.但是在最後一行中,你說它在@ Var1中有9個! – Lucky

+1

儘自己最大的忙,並儘快規範你的數據庫。逗號分隔的字符串是** NOT **是有效的數據類型! –

回答

1

可以轉換爲XML和使用XQuery:

DECLARE @var1 VARCHAR(100) = '37,39,41,43' 
DECLARE @table TABLE(Id INT, Nos VARCHAR(max)) 
INSERT INTO @table VALUES(1,'37,35,46'),(2,'37,38'),(3,'39,40'),(4,'37,38,39,40,41,42,43,44,45,46') 

SELECT * FROM @table WHERE cast('<n>' + replace(@var1,',','</n><n>') + '</n>' AS XML).exist('//n/.[not(contains(sql:column("nos"),.))]') = 0 
UNION 
SELECT * FROM @table WHERE cast('<n>' + replace(Nos,',','</n><n>') + '</n>' AS XML).exist('//n/.[not(contains(sql:variable("@var1"),.))]') = 0 
+0

謝謝。但沒有按預期工作。 DECLARE @ var1 VARCHAR(100)= '37,39,41,43' DECLARE @table TABLE(Id INT,Nos VARCHAR(max)) INSERT INTO @table VALUES(1,'' 37,35,46 '),(2,'37,38'),(3,'39,40' ),(4,'37,38,39,40,41,42,43,44,45, 46 ') SELECT * FROM @table WHERE鑄造(' '+替換(NOS,', '' ')+' 'AS XML).exist(' // N/[不(包含(sql:variable(「@ var1」),。))]')= 0' – Sudha

+0

當我運行它時,它不返回我期望的行,因爲在每個列中至少有一個不在列表中的數字;這不是你所需要的嗎?你對這個樣本有什麼期望的輸出? – Jayvee

+0

我預計(4,'37,38,39,40,41,42,43,44,45,46'),因爲@ var1的所有值(37,39,41,43)出現在第4條記錄中。 – Sudha

0

這仍可以進一步降低,但思路如下,

創建SplitString功能,

CREATE FUNCTION SplitString 
( 
     @Input NVARCHAR(MAX), 
     @Character CHAR(1) 
) 
RETURNS @Output TABLE (
     Item NVARCHAR(1000) 
) 
AS 
BEGIN 
     DECLARE @StartIndex INT, @EndIndex INT 

     SET @StartIndex = 1 
     IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character 
     BEGIN 
      SET @Input = @Input + @Character 
     END 

     WHILE CHARINDEX(@Character, @Input) > 0 
     BEGIN 
      SET @EndIndex = CHARINDEX(@Character, @Input) 

      INSERT INTO @Output(Item) 
      SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1) 

      SET @Input = rtrim(ltrim(SUBSTRING(@Input, @EndIndex + 1, LEN(@Input)))) 
     END 

     RETURN 
END 
GO 

使用以下系列查詢並定製它,

DECLARE @t TABLE (ID INT, Nos VARCHAR(8000)) 
INSERT @t 
VALUES (1, 
     '5, 3'), (2, 
        '3, 6, 8'), (3, 
           '3, 9, 8'),(4, 
              '8') IF OBJECT_ID('tempdb..#Temp') IS NOT NULL 
DROP TABLE #Temp 
SELECT * INTO #Temp 
FROM 
    (SELECT ID, 
      LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS Nos 
    FROM 
    (SELECT ID, 
      CAST('<XMLRoot><RowData>' + REPLACE(Nos,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x 
     FROM @t)t CROSS APPLY x.nodes('/XMLRoot/RowData')m(n)) P 
SELECT '3, 5, 6, 8' 
SELECT '(1==> 5, 3), (2==> 3, 6, 8), (3 ==> 3, 9, 8),(4 ==> 8)' 
SELECT * 
FROM #Temp 
SELECT Item 
FROM dbo.SplitString('3, 5, 6, 8', ',') 
SELECT '-- Group By ' 
SELECT Id, 
     Count(Nos) C 
FROM #Temp 
GROUP BY Id 
SELECT Id, 
     Count(Nos) C 
FROM 
    (SELECT Item 
    FROM dbo.SplitString('3, 5, 6, 8', ',')) X 
JOIN 
    (SELECT Id, 
      Nos 
    FROM #Temp) Y ON X.Item = Y.Nos 
GROUP BY Id 
SELECT '-- Final check' 
SELECT T.* 
FROM 
    (SELECT Id, 
      Count(Nos) C 
    FROM #Temp 
    GROUP BY Id) P 
JOIN 
    (SELECT Id, 
      Count(Nos) C 
    FROM 
    (SELECT Item 
     FROM dbo.SplitString('3, 5, 6, 8', ',')) X 
    JOIN 
    (SELECT Id, 
      Nos 
     FROM #Temp) Y ON X.Item = Y.Nos 
    GROUP BY Id) Q ON P.Id = Q.Id 
AND P.C = Q.C 
JOIN #Temp T ON T.Id = P.Id 
相關問題