Sql 查找所有具有按升序时间排序的X标记的记录,但是,应首先对与大多数标记匹配的记录进行分组
好的,这有点难以解释,标题也不是最好的:/但是,基本上,我有3个表,我正在尝试编写一个查询,返回两个级别的排序。第一个由每行的“标记”数量决定,第二个由该行的创建时间决定Sql 查找所有具有按升序时间排序的X标记的记录,但是,应首先对与大多数标记匹配的记录进行分组,sql,postgresql,tags,Sql,Postgresql,Tags,好的,这有点难以解释,标题也不是最好的:/但是,基本上,我有3个表,我正在尝试编写一个查询,返回两个级别的排序。第一个由每行的“标记”数量决定,第二个由该行的创建时间决定 Table1: Items * ID * Name * CreatedAt Table2: Tags * ID * Name Table3: TaggedItems * TagID * ItemID 我想列出所有有一个或多个标记的项目,按创建时的升序排列。但是,这里是我遇到问题的地方,我希望排
Table1: Items
* ID
* Name
* CreatedAt
Table2: Tags
* ID
* Name
Table3: TaggedItems
* TagID
* ItemID
我想列出所有有一个或多个标记的项目,按创建时的升序排列。但是,这里是我遇到问题的地方,我希望排序基于与项目匹配的标记的数量,并且在该排序中,应用升序标准
那么,假设我有:
Item1 -> CreatedAt(0), Tags(A, B)
Item2 -> CreatedAt(0), Tags(A)
Item3 -> CreatedAt(1), Tags(B)
Item4 -> CreatedAt(1), Tags(A, B)
然后,搜索带有标记A和B的所有项目必须首先返回Item1
和Item4
,并按升序CreatedAt
排序。然后Item2
和Item3
并按CreatedAt
升序排序。因此,结果将是:
* Item1
* Item4
* Item2
* Item3
我没有SQL方面的经验,所以如果我能正确解释的话,可能有很多众所周知的解决方案
谢谢你的帮助 您可以执行条件排序:
select i.*, x.no_tags
from items
cross join lateral (
select count(*) no_tags
from taggedItems ti
inner join tags t on t.id = ti.tagID
where ti.ItemID = i.ID and t.name in ('A', 'B')
) x
order by
(x.no_tags > 1) desc,
case when x.no_tags > 1 then i.createdAt end desc,
createdAt
查询从items
表开始,然后使用横向联接
来检索属于目标列表的匹配标记的计数(我在示例中使用了('a','B')
)。然后,orderby
将具有超过1个标记的项放在第一位,并使用条件表达式按降序日期对它们进行排序;只有一个标记的记录不被此排序标准考虑,而是属于按升序日期排序的最后一个排序标准。请尝试:
select i.id,i,name
from Items i join TaggedItems ti on i.ID=ti.ItemID
join Tags t on t.ID=ti.TagID
group by i.id,i,name
order by count(*),CreatedAt
短语
orderbycount(*)
适用于大多数数据库服务器。使用左
将项
连接到标记数据项
(以防项根本没有任何标记)并按项分组。最后按标签数量降序排序,然后按日期排序:
SELECT i.name
FROM Items i LEFT JOIN TaggedItems t
ON t.ItemID = i.ID
GROUP BY i.ID, i.Name
ORDER BY COUNT(t.TagID) DESC, i.CreatedAt
不需要表格标签。
但是如果您想要标签列表的结果,比如'a'
和'B'
,那么:
SELECT i.name
FROM Items i
LEFT JOIN TaggedItems ti ON ti.ItemID = i.ID
LEFT JOIN Tags t ON t.ID = ti.TagID AND t.Name IN ('A', 'B')
GROUP BY i.ID, i.Name
ORDER BY COUNT(t.ID) DESC, i.CreatedAt