如何解决SQL加入过滤器和偏移量
我需要创建一个 sql 查询来返回带有标签的图像。结果应按某些列排序,并按 UserID 和标签进行过滤。结果应该是分页的。
有一条sql语句
SELECT img.*,t.Name
FROM Image img
INNER JOIN ImageTag it on it.ImageID = img.ImageID
INNER JOIN Tag t on t.TagID = it.TagID
WHERE img.UserID = 1 and t.Name in ('first','second')
ORDER BY img.CreatedAt OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY
此请求未按预期工作。我希望得到 50 张图像,但它们将与标签结合,结果将类似于 ...
| Image.ImageID | Tag.Name | ... | | 1 | First | ... | | 1 | Second | ... | | 2 | First | ... | | 3 | First | ... | ....
如何获得 50 张图片而不是 50 行?
解决方法
您可以更改 order by
以交错图像:
ORDER BY ROW_NUMBER() OVER (PARTITION BY img.ImageID ORDER BY NEWID()),img.CreatedAt
OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY
基本上,这会枚举每个图像的行,返回“第一”行。注意:如果您没有 50 张图片,那么随着代码移动到第二个标签,将会有重复的图片。
如果您希望每张图片只有一行带有所有标签,您可以使用 APPLY
:
SELECT img.*,t.tags
FROM Image img CROSS APPLY
(SELECT STRING_AGG(t.Name,',') as tags
FROM ImageTag it JOIN
Tag t
ON t.TagID = it.TagID
WHERE it.ImageID = img.ImageID AND
t.Name IN ('first','second')
) t
WHERE img.UserID = 1
ORDER BY img.CreatedAt OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY
这会聚合子查询中每个图像的标签,因此每个图像只返回一行。这将标签连接在一起。当然,您也可以使用其他聚合函数,例如 MIN()
或 MAX()
。
您也可以使用:
MIN(t.Name) + (CASE WHEN MIN(t.Name) <> MAX(t.Name) THEN ',' + MAX(t.Name) ELSE '' END)
,
SELECT img.*,t.Name
FROM Image img
INNER JOIN ImageTag it on it.ImageID = img.ImageID
INNER JOIN Tag t on t.TagID = it.TagID
INNER JOIN (SELECT ImageID FROM Image ORDER BY CreatedAt OFFSET 0 ROWS FETCH NEXT 50
ROWS ONLY) img1 ON img1.ImageID=img.ImageID
WHERE img.UserID = 1 and t.Name in ('first','second')
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。