我想返回匹配csv的所有值作为传统" in"运算符匹配csv中的任何项目:
SELECT * FROM @MyTable
WHERE [UserID] IN (1,2)
上述查询不能满足我的目的,因为我想匹配具有组记录的行。在我的情况下,group by 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&#39 ;;我希望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
答案 0 :(得分:2)
使用split函数,可以执行OUTER JOIN并确保没有NULL行:
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中的所有值匹配,为什么会出现这种情况呢?当有多个匹配时,确定返回哪一行的规则是什么?