我有2个表,作业和Assignment_tags
ASSIGNMENTS
-----------
ASSIGNMENTID int
ASSIGNMENTNAME nvarchar(50)
ASSIGNMENT_TAGS
---------------
TAGID int
ASSIGNMENTID int
TAGNAME nvarchar(50)
每个作业可以有多个标签。
我需要一个SQL查询来返回给定标记列表的分配。我需要这些作业才能拥有所有这些标签。
ASSIGNMENTS Table
-----------------
ASSIGNMENTID ASSIGNMENTNAME
1 Assignment 1
2 Assignment 2
3 Assignment 3
ASSIGNMENT_TAGS Table
---------------------
TAGID ASSIGNMENTID TAGNAME
1 1 Some Tag
2 2 Some Tag
3 1 Another Tag
4 3 A Different Tag
5 2 A Different Tag
如果我将“Some Tag,Another Tag”作为逗号分隔标记列表作为存储过程的输入参数提供,我希望查询返回ASSIGNMENTID 1,因为此赋值具有两个标记。
我确信这很容易,但我的大脑今天似乎没有用。任何帮助将不胜感激。
答案 0 :(得分:0)
使用逗号分隔的列表很痛苦。但你可以这样做:
select att.assignmentid
from assignmenttags att
where ',' + @tags + ',' = '%,' + att.tagname + ',%'
group by att.assignmentid
having count(distinct att.tagname) = (length(@tags) -
length(replace(@tags, ',', '')
) + 1;
这假设输入列表只有逗号分隔值,并且列表中没有重复值。
答案 1 :(得分:0)
首先我建议使用这个有用的函数将anychar-delimited-list字符串转换为表。
CREATE FUNCTION [dbo].[Split]
(
@String NVARCHAR(4000),
@Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
WITH Split(stpos,endpos)
AS(
SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
UNION ALL
SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
FROM Split
WHERE endpos > 0
)
SELECT 'ID_Split' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
'Data' = RTRIM(LTRIM(SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)))
FROM Split
)
GO
使用此功能,您可以知道哪个ASSINGMENTSID至少与列表中的一个标签无关。
DECLARE @Comma_delimited_tag_list VARCHAR(500) = 'Some Tag,Another Tag'
DECLARE @Delimiter VARCHAR(1) = ','
SELECT
A.ASSIGNMENTID, B.*, AT.*
FROM [dbo].[Split](@Comma_delimited_tag_list, @Delimiter) B
FULL JOIN ASSIGNMENTS A ON 1 = 1
LEFT JOIN ASSIGNMENT_TAGS AT ON AT.ASSIGNMENTID = A.ASSIGNMENTID AND AT.TAGNAME = B.Data
WHERE
AT.ASSIGNMENTID IS NULL
结果:
ASSIGNMENTID ID_Split Data TAGID ASSIGNMENTID TAGNAME
------------ -------------------- ----------- ----------- ------------ ----------------
2 2 Another Tag NULL NULL NULL
3 1 Some Tag NULL NULL NULL
3 2 Another Tag NULL NULL NULL
最后知道这一点,我们可以知道哪些ASSIGNMENTID适合嵌套以下查询的所有标签。
DECLARE @Comma_delimited_tag_list VARCHAR(500) = 'Some Tag,Another Tag'
DECLARE @Delimiter VARCHAR(1) = ','
SELECT
A.*
FROM ASSIGNMENTS A
LEFT JOIN
(
SELECT
A.ASSIGNMENTID
FROM [dbo].[Split](@Comma_delimited_tag_list, @Delimiter) B
FULL JOIN ASSIGNMENTS A ON 1 = 1
LEFT JOIN ASSIGNMENT_TAGS AT ON AT.ASSIGNMENTID = A.ASSIGNMENTID AND AT.TAGNAME = B.Data
WHERE
AT.ASSIGNMENTID IS NULL
) B
ON A.ASSIGNMENTID = B.ASSIGNMENTID
WHERE
B.ASSIGNMENTID IS NULL
ASSIGNMENTID | ASSIGNMENTNAME
------------ | --------------
1 | Assignment 1
适用于任何@Delimiter值的列表。
希望它适合你。