Sql 匹配所有行的In运算符
我想返回匹配csv的所有值,因为传统的“in”运算符匹配csv中存在的任何项目:Sql 匹配所有行的In运算符,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我想返回匹配csv的所有值,因为传统的“in”运算符匹配csv中存在的任何项目: SELECT * FROM @MyTable WHERE [UserID] IN (1,2) 上面的查询不适用于我的目的,因为我想匹配一个组中同时包含两条记录的行。在我的案例中,组将按typeid进行设置 用于填充表的查询: DECLARE @MyTable TABLE ( [TypeID] INT , [UserID] INT ) INSERT INTO @MyTab
SELECT * FROM @MyTable
WHERE [UserID] IN (1,2)
上面的查询不适用于我的目的,因为我想匹配一个组中同时包含两条记录的行。在我的案例中,组将按typeid进行设置
用于填充表的查询:
DECLARE @MyTable TABLE
(
[TypeID] INT ,
[UserID] INT
)
INSERT INTO @MyTable
SELECT 1 ,
1
UNION
SELECT 1 ,
2
UNION
SELECT 2 ,
1
UNION
SELECT 2 ,
2
UNION
SELECT 2 ,
3
UNION
SELECT 3 ,
1
UNION
SELECT 3 ,
2
UNION
SELECT 3 ,
3
UNION
SELECT 3 ,
4
为了查询上面的表,我输入了userid字符串
DECLARE @UserIDString VARCHAR(256)
以下是我的要求:
当输入为“1,2”时;我希望typeid 1作为输出,因为该组的所有记录都以csv形式存在
如果输入为“1,2,3”;2应返回typeid,因为该组具有csv中存在的所有值
如果输入为“1,2,3,4”;3应返回typeid,因为该组具有csv中存在的所有值
编辑:
以下是拆分csv的拆分函数:
CREATE FUNCTION [dbo].[Split_String]
(
@inputString NVARCHAR(2000) ,
@delimiter NVARCHAR(20) = ' '
)
RETURNS @Strings TABLE
(
[position] INT IDENTITY
PRIMARY KEY ,
[value] NVARCHAR(2000)
)
AS
BEGIN
DECLARE @index INT
SET @index = -1
WHILE ( LEN(@inputString) > 0 )
BEGIN-- Find the first delimiter
SET @index = CHARINDEX(@delimiter, @inputString)
-- No delimiter left?
-- Insert the remaining @inputString and break the loop
IF ( @index = 0 )
AND ( LEN(@inputString) > 0 )
BEGIN
INSERT INTO @Strings
VALUES ( RTRIM(LTRIM(CAST(@inputString AS NVARCHAR(2000))) ))
BREAK
END
-- Found a delimiter
-- Insert left of the delimiter and truncate the @inputString
IF ( @index > 1 )
BEGIN
INSERT INTO @Strings
VALUES ( RTRIM(LTRIM(CAST(LEFT(@inputString, @index - 1) AS NVARCHAR(2000)) ) ))
SET @inputString = RIGHT(@inputString,
( LEN(@inputString) - @index ))
END -- Delimiter is 1st position = no @inputString to insert
ELSE
SET @inputString = CAST(RIGHT(@inputString,
( LEN(@inputString) - @index )) AS NVARCHAR(2000))
END
RETURN
END
GO
编辑:
谢谢@Tab,经过进一步修改,我找到了解决方案:
DECLARE @InputString VARCHAR(256)
DECLARE @Count VARCHAR(256)
--SET @InputString = '1,2'
DECLARE @DummyTable TABLE
(
[position] INT ,
[value] INT
)
INSERT INTO @DummyTable
( [position] ,
[value]
)
SELECT [position] ,
[value]
FROM [dbo].[Split_String](@InputString, ',')
SELECT @Count = COUNT(1)
FROM @DummyTable
SELECT TypeID
FROM @MyTable
WHERE TypeID NOT IN (
SELECT TypeID
FROM @MyTable T
LEFT OUTER JOIN @DummyTable ss ON t.UserId = ss.Value
WHERE ss.Position IS NULL )
GROUP BY TypeID
HAVING COUNT(TypeID) = @Count
使用split函数,可以进行外部联接,并确保没有空行:
SELECT TypeID
FROM @MyTable
WHERE TypeID NOT IN (
SELECT TypeID
FROM @MyTable t
LEFT OUTER JOIN [dbo].[Split_String] (@InputString,',') ss
ON t.UserId=ss.Value
WHERE ss.Position IS NULL
) x
未经测试,但我认为应该这样做
但是,这应返回满足以下要求的所有类型:
该组拥有csv中的所有记录
在您的问题中,您似乎暗示只应返回一行,但如果有多行匹配csv中的所有值,为什么会出现这种情况?当存在多个匹配项时,确定返回哪一行的规则是什么?使用拆分函数并执行联接,确保函数中的所有行在表中都有匹配项。我已添加了正在使用的拆分函数。你能帮我查询一下结果吗?我被困在这一部分“确保函数中的所有行在表中都有匹配项”中,因为拆分器运行时,while循环版本的速度非常慢。理想情况下,最好不要在t-sql中这样做,但如果您必须阅读本文,找到比while循环快光年的几个版本。哇!那篇文章看起来非常好。谢谢肖恩,我一定会经历的。