【问题标题】:How do you select a specific row from a group in a group_by statement in python SQLAlchemy (sqlite)?如何在 python SQLAlchemy(sqlite)的 group_by 语句中从组中选择特定行?
【发布时间】:2021-02-26 14:57:58
【问题描述】:

我遇到了看起来应该是一个非常简单的查询的问题。对于每个唯一名称,我只想返回年龄最小的用户的名称

这是一个基本示例http://sqlfiddle.com/#!9/ce2f7e4/16

示例数据库:

 +-----+-------+-----+
| id  | name  | age |
+-----+-------+-----+
|  1  | joe   |  50 |
|  2  | joe   |  25 |
|  3  | fred  |  25 |
|  4  | fred  |  50 |
|  5  | bob   |  30 |
+-----+-------+-----+

这是我正在尝试的当前尝试

session.query(User).group_by(User.name).order_by(User.name,User.age).all()

在原始 SQL 中:

SELECT t.id,t.name,t.age from user t
GROUP BY t.name
ORDER BY t.name, t.age;

但是,正如您在示例中看到的那样,这会返回错误的结果。我根据需要为每个名称获取一行,但所选用户不是每个唯一名称年龄最低的用户。

期望的结果:

+-----+-------+-----+
| id  | name  | age |
+-----+-------+-----+
|  2  | joe   |  25 |
|  3  | fred  |  25 |
|  5  | bob   |  30 |
+-----+-------+-----+

如您所见,对于每个唯一名称,返回的行应该是具有该名称且年龄最小的用户。如何编写 sqlalchemy 查询来获得此结果?谢谢

【问题讨论】:

    标签: python sql sqlite sqlalchemy


    【解决方案1】:

    我不知道如何将其转换为 sqlachemy,但在直接 SQL 中,您会使用像 row_number() 这样的排名窗口函数:

    WITH ranked(id, name, age, rn) AS
      (SELECT id, name, age, row_number() OVER (PARTITION BY name ORDER BY age) AS rn
       FROM test)
    SELECT id, name, age
    FROM ranked
    WHERE rn = 1
    ORDER BY name, age;
    

    DB<>Fiddle demonstration

    或特定于 Sqlite 的:

    SELECT id, name, min(age) AS age
    FROM test
    GROUP BY name
    ORDER BY name, age;
    

    【讨论】:

      【解决方案2】:

      如果你想要最年轻的行,你可以使用:

      select t.*
      from t
      where t.age = (select min(t2.age) from t t2 where t2.name = t.name);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-17
        • 2011-07-05
        • 2014-02-22
        • 2016-04-23
        • 2014-06-24
        • 2010-12-18
        相关资源
        最近更新 更多