【问题标题】:postgres: join, group by, order by. Is my query wrong?postgres:加入、分组、排序。我的查询错了吗?
【发布时间】:2017-09-28 17:48:31
【问题描述】:

我的桌子

CREATE TABLE IF NOT EXISTS members(
    group_id BIGINT, 
    amount INT, 
    updated_date timestamp)

CREATE TABLE IF NOT EXISTS supergroups_ref(
    group_id BIGINT PRIMARY KEY, 
    title TEXT DEFAULT NULL, 
    message_date timestamp)

CREATE TABLE IF NOT EXISTS supergroups(
    group_id BIGINT PRIMARY KEY, 
    lang TEXT DEFAULT NULL, 
    last_date timestamp DEFAULT NULL)

成员中的数据示例

(3, 90, date)
(1, 15, date)
(2, 200, date)
(1, 28, date)
(2, 300, date)
(1, 80, date)

supergroups_ref 中的数据示例:

(1, 'title', date)
(2, 'title2', date)
(3, 'title3', date)

超组中的数据示例:

(1, 'en', date)
(2, 'it', date)
(3, 'it', date)

我希望能够做一个查询 从表中的成员只获取按“updated_date”DESC 排序的最新行,然后将它们加入超级组,这样超级组中的每个 group_id 都具有正确的最新成员数量。 现在我想在 supergroups_ref 中附加另一个左连接标题信息

我想按成员表的数量对它们进行排序。

我试图这样做,但我不确定我做得对:

SELECT sub.group_id, sub.amount, sub.title
FROM (
    SELECT s.group_id, m.amount, s_ref.title
    FROM  supergroups AS s
    LEFT OUTER JOIN members AS m
    ON m.group_id = s.group_id
    LEFT OUTER JOIN supergroups_ref AS s_ref
    ON s_ref.group_id = s.group_id
    ORDER BY m.updated_date DESC
) AS sub
GROUP BY sub.group_id, sub.amount, sub.title
ORDER BY sub.amount DESC

恐怕:

  1. 我在查询中做错了什么
  2. 我的查询过于复杂了

期望的结果是: [(2, 200, 'title2'), (3, 90, 'title3'), (1, 15, 'title1')] 每个元素的第二个元素是最近的成员数量,因为该数量也将日期存储在成员表中。元组是按那个排序的

【问题讨论】:

  • 你能编辑你的帖子并输入你想要的输出吗?对您的需求进行“可视化”。
  • @Dan 我现在做到了!
  • 如果您使用实际日期而不是“日期”一词会有所帮助,这样选择逻辑会更清晰。

标签: postgresql join group-by


【解决方案1】:

如果我明白了,这就是你需要的:

SELECT members.*,supergroups.lang,supergroups_ref.title
FROM
-- Window function to get only de last_date:
    (SELECT last_members.group_id,last_members.amount
    FROM
     (SELECT *,row_number() OVER (PARTITION BY group_id
     ORDER BY updated_date DESC) as row FROM members)last_members
    WHERE last_members.row=1)members
-- Joins with other tables
LEFT JOIN supergroups ON members.group_id=supergroups.group_id
LEFT JOIN supergroups_ref ON supergroups.group_id=supergroups_ref.group_id

这应该返回:

group_id |  amount  |   lang  | title
--------------------------------------
1        |  15      |   en    | title
2        |  200     |   it    | title2
3        |  90      |   it    | title3

要让这个查询工作,你需要使用窗口函数,这里有一篇关于它们的好文章Understanding Window Functions

【讨论】:

    猜你喜欢
    • 2011-08-05
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    相关资源
    最近更新 更多