简体   繁体   English

Esqueleto / raw SQL —是否按另一个表的排序结果对查询进行排序?

[英]Esqueleto/raw SQL — Sorting a query by the result of a sort on another table?

I actually am a little new to how SQL works -- i've always let my ORM's handle everything for me. 实际上,我对SQL的工作方式有些陌生-我总是让ORM替我处理一切。 But this in this case Persistent doesn't expose this kind of functionality so I'm at lost at what to do. 但是在这种情况下,Persistent不会公开这种功能,所以我迷失了该做什么。

I have a many-to-many relationship: 我有多对多关系:

+------------+
| Entries    |
+----+-------+
| id | date  |
+----+-------+
| 1  | Jan 1 |
+----+-------+
| 2  | Jan 2 |
+----+-------+
| 3  | Jan 3 |
+----+-------+

+------------+
| Tags       |
+------------+
| id | label |
+----+-------+
| 1  | Apple |
+----+-------+
| 2  | Boat  |
+----+-------+
| 3  | Car   |
+----+-------+

+-------------------+
| EntryTags         |
+----------+--------+
| entry_id | tag_id |
+----------+--------+
| 1        | 1      |
+----------+--------+
| 1        | 2      |
+----------+--------+
| 2        | 2      |
+----------+--------+
| 3        | 3      |
+----------+--------+

And I want to sort tags primarily by the date of their most recent entry (descending), secondarily by their label (ascending). 我想首先按标签的最新输入日期(降序)对标签进行排序,其次按标签的标签(升序)进行排序。

Tag Car 's most recent entry is on Jan 3rd, so it goes first. Tag Car的最新条目是1月3日,因此排名第一。 Tag Apple 's most recent entry is January 2nd, but so is tag Boat . 标签Apple的最新的条目是1月2日,但这样的标签Boat However, the label Apple comes before the label Boat alphabetically, so Apple is 2nd and Boat is 3rd: 但是,标签Apple按字母顺序在标签Boat之前,因此Apple是2nd,而Boat是3rd:

returns:
1. Tag w/ id 3
2. Tag w/ id 1
3. Tag w/ id 2

Through my research I've figured out that I need some kind of combination of joins to do this. 通过我的研究,我发现我需要某种形式的连接来做到这一点。 However so far I've only found soutions for one-to-many relations (sorting topics in a thread by their most recent post), and I think I understand them, but none involving these three-way joins for many-to-many relations. 但是到目前为止,我只发现了一对多关系(按主题的最新帖子对主题进行排序),我认为我理解它们,但是没有涉及到多对多关系的三向联接关系。

I'm including raw sql as a possible answer because I think I'm really just asking for the sql way to do it, and even though I'm using Esqueleto for my SQL bindings, I think that once I understand the SQL, the translation to Esqueleto will be straightforward. 我将原始sql作为可能的答案,因为我认为我实际上只是在寻求sql的方式,即使我将Esqueleto用于SQL绑定,我也认为一旦我了解了SQL,翻译成Esqueleto很简单。 I'm using postgresql as my backend, but I'd rather not use postgres-specific things because my bindings are for general backends. 我将postgresql用作后端,但我不希望使用postgres专用的东西,因为我的绑定是针对通用后端的。

Anyone have any idea where I can start? 有人知道我可以从哪里开始吗? What kind of joins should I be looking at and how do I sort through most recent entry? 我应该查看哪种联接,如何对最新的联接进行排序?

Another solution: 另一个解决方案:

select t.id as tag_id, t.label as tag, max(date) as date from Tags t
join EntryTags et on t.id=et.tag_id
join Entries e on e.id=et.entry_id
group by t.label,t.id
order by date desc,tag

which returns: 返回:

tag_id  tag    date   
------  -----  -----  
1       Apple  jan 3  
3       Car    jan 3  
2       Boat   jan 2  

(In your data, Apple's most recent entry is January 3, not January 2.) (在您的数据中,Apple的最新条目是1月3日,而不是1月2日。)

Joins in Postgres are implicity "inner joins". Postgres中的联接是隐式的“内部联接”。 If you may have tags without entries, you will want to change the joins to left joins. 如果您可能有没有条目的标签,则需要将联接更改为左联接。

SQL Fiddle SQL小提琴

Your sample data does not fit the text. 您的样本数据不适合文本。 The table entrytags should be 表条目标记应为

(1, 1),
(1, 2),
(2, 2),
(2, 1),
(3, 3);

select id, label
from (
    select distinct on (t.id) e.date, t.label, t.id
    from
        entries e
        inner join
        entrytags et on et.entry_id = e.id
        inner join
        tags t on t.id = et.tag_id
    order by t.id, e.date desc, t.label
) s
order by "date" desc, label

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM