我有三张表Post
,PostTagMap
和Tag
。 PostTagMap
是用于映射具有多个标签的单个帖子的联结表。 我尝试编写查询以将所有帖子都归属于标记名称。
发布表
Id Name
1 Post #1
2 Post #2
标记表
Id Name
1 JS
2 CSS
PostTagMap表
Id PostId TagId
1 1 1
2 1 2
(编辑PostTagMap数据以匹配相关问题)
SELECT P.Id FROM Post P
LEFT JOIN PostTagMap PTM ON P.Id = PTM.PostId
INNER JOIN Tag T ON PTM.TagId = T.Id
WHERE T.Name = ISNULL(@Tag, T.Name)
当@Tag
为NULL
时,我只获取帖子ID 1的详细信息而不是2.上述查询有什么问题?
也在下面尝试,
SELECT P.Id FROM Post P
LEFT JOIN PostTagMap PTM ON P.Id = PTM.PostId
LEFT JOIN Tag T ON PTM.TagId = T.Id
WHERE T.Name = ISNULL(@Tag, T.Name)
以上也没有回复2的帖子细节。
SELECT P.Id FROM Post P
LEFT JOIN PostTagMap PTM ON P.Id = PTM.PostId
LEFT JOIN Tag T ON PTM.TagId = T.Id AND T.Name = ISNULL(@Tag, T.Name)
甚至将@Tag作为" JS"。
返回所有内容答案 0 :(得分:2)
我尝试了所有查询,但一切正常,请尝试此操作
每个查询都应该像它应该的那样工作,也许问题不在于查询
KeyUp
仅按预期返回帖子1而不是所有内容
编辑:
我理解您的问题现在尝试我的查询
SELECT P.Id FROM Post P
LEFT JOIN PostTagMap PTM ON P.Id = PTM.PostId
INNER JOIN Tag T ON PTM.TagId = T.Id
WHERE T.Name = ISNULL('Css', T.Name)
选择所有DECLARE @Tag NVARCHAR(50)
set @Tag = NULL
SELECT P.Id FROM Post P
LEFT JOIN PostTagMap PTM ON P.Id = PTM.PostId
LEFT JOIN Tag T ON PTM.TagId = T.Id
WHERE @Tag IS NULL OR T.Name = @Tag
GROUP BY P.Id
,然后添加Post
,以防WHERE @Tag IS NULL
为空,@Tag
的其他人希望它可以提供帮助
答案 1 :(得分:2)
你的问题是
WHERE T.Name = ISNULL(@Tag, T.Name)
因为T.Name = T.Name
T.Name IS NULL
为FALSE
更改
中的where子句WHERE (T.Name = @Tag) or (@Tag IS NULL)
同时使用LEFT JOIN
或者内部将过滤掉连接表中没有条目的行
答案 2 :(得分:0)
我跑:
SELECT P.Id FROM Post P
LEFT JOIN PostTagMap PTM ON P.Id = PTM.PostId
LEFT JOIN Tag T ON PTM.TagId = T.Id
WHERE T.Name = COALESCE(@Tag, T.Name)
当@Tag为NULL时,它会返回所有内容。 我不知道这是否符合您的期望。
这是我的Fiddle
答案 3 :(得分:0)
因为你对依赖于@Tag
条件的行使用LEFT JOIN,所以你基本上不会过滤Post
条记录,你总是得到所有这些。
如果存在匹配的行,则确实从左连接表中选择其他数据,但这不会影响返回的Post
个记录。
你需要做什么:
如果@Tag为空 - 不过滤
否则 - 应用过滤器,并使用内部加入执行:
DECLARE @Tag NVARCHAR(50) = 'Js' -- or NULL
SELECT P.Id FROM Post P
WHERE @Tag IS NULL
OR EXISTS (
SELECT 1 FROM PostTagMap M
JOIN Tag T ON M.TagId = T.Id
WHERE M.PostId = P.Id
AND T.Name = @Tag
)