代码之家  ›  专栏  ›  技术社区  ›  91DarioDev

博士后:加入、分组、排序。我的问题错了吗?

  •  1
  • 91DarioDev  · 技术社区  · 7 年前

    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\u date”DESC排序的最新行,并在超群上左连接它们,以便超群中的每个group\u id都具有最新的成员数量。

    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
    

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

    1 回复  |  直到 7 年前
        1
  •  1
  •   Dan    7 年前

    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