查找与其他字符串匹配的字符串的一部分SQL
我有一个赋值给变量say @ var1 ='3,5,6,8'的值。我有一个表,其中有一些随机数字组合的列,以逗号分隔。 PFB试样台查找与其他字符串匹配的字符串的一部分SQL
我所需要的表中的所有值除了ID 3,因为它在其组合“3,9,8”具有9。
我想回复如下。
期望输出应该只包含的ID 1,2和4.
原因是,任何/所有存在于@ var1的值的应存在于NOS和它不应该有一个没有这是不出现在@ var1中。 Id 3是后者情况下的一个例子,其中包含9不属于@ var1的部分。
我的输出应该有标识1,2和4,而不是3
能否请您提出一些想法做呢?
可以转换为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
谢谢。但没有按预期工作。 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铸造('
当我运行它时,它不返回我期望的行,因为在每个列中至少有一个不在列表中的数字;这不是你所需要的吗?你对这个样本有什么期望的输出? – Jayvee
我预计(4,'37,38,39,40,41,42,43,44,45,46'),因为@ var1的所有值(37,39,41,43)出现在第4条记录中。 – Sudha
这仍可以进一步降低,但思路如下,
创建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
您应该将这4个值作为不同的参数传递。如果你不这样做,那么在运行NOT LIKE –
Pl之前,你需要分离出这些数据。很清楚你需要什么!在第一行中,@ Var1有3,5,6和8.但是在最后一行中,你说它在@ Var1中有9个! – Lucky
尽自己最大的忙,并尽快规范你的数据库。逗号分隔的字符串是** NOT **是有效的数据类型! –