微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SQL加入过滤器和偏移量

如何解决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 举报,一经查实,本站将立刻删除。