【问题标题】:How to query collection of objects while grouping by a property如何在按属性分组时查询对象集合
【发布时间】:2018-11-25 13:18:18
【问题描述】:

所以我正在尝试编写一个查询,该查询将选择在某个属性上不同的对象集合。

行动:

+-----+-----------+-----+
| id  | timestamp | ... |
+-----+-----------+-----+
|  10 | 16:04     | ... |
|  11 | 16:06     | ... |
|  12 | 16:08     | ... |
|  13 | 16:09     | ... |
|  14 | 16:10     | ... |
+-----+-----------+-----+

Foo版本:

+----+--------+-----------+-------------------+
| id | foo_id | action_id | foo_zab           |
+----+--------+-----------+-------------------+
|  1 |      1 |        10 | xx                |
|  2 |      2 |        11 | yy                |
|  3 |      3 |        12 | zz                |
|  4 |      3 |        13 | zy                |
|  5 |      3 |        14 | zx                |
+----+--------+-----------+-------------------+

富:

+----+-----+
| id | zab |
+----+-----+
|  1 | xx  |
|  2 | yy  |
|  3 | zx  |
+----+-----+

一个场景是由一组 foo 组成的。我正在尝试跟踪每个特定 foo 随着时间的变化。因此,每次对 foo 进行更改时,都会记录导致该更改的操作,并将 foo 的一些属性的副本存储在 foo_versions 表中

我正在寻找的是“特定动作中 foos 的状态”。因此,虽然动作 #11 仅专门链接到 foo,但动作 #11 的场景状态实际上包含 3 个 foo,它们的版本是 foo_version #1、#2 和 #5

我需要构造一个查询“对于指定的动作,给我场景的表示”

对于动作 #10,场景将是 [<foo_version #1>]

对于动作 #12,场景将是 [<foo_version #1>, <foo_version #2>, <foo_version #3>]

这就是棘手的地方。对于动作#14,场景的表示是[<foo_version #1>, <foo_version #2>, <foo_version #5>]。 Foo 版本 #3、#4 和 #5 都引用相同的 foo。所以,foo 版本 #3 和 #4 会被 #5 覆盖。

我正在使用这个 sqlalchemy 查询:

stmt = db.session.query(Action).filter(Action.timestamp <= action.timestamp).subquery()
action_alias = aliased(Action, stmt)

foo_versions = db.session.query(FooVersion) \
                         .join(Action) \
                         .join(action_alias, FooVersion.action) \
                         .filter(Action.frame_id == frame.id) \
                         .all()

我得到的结果是

[<foo_version #1>, <foo_version #2>, <foo_version #3>, <foo_version #4>, <foo_version #5>]]]
                                     |____________|    |____________|
                                           ^                 ^
                                           |                 |
I need to get rid of these versions     -> |                 |
since they have been overwritten 

【问题讨论】:

    标签: python mysql orm sqlalchemy


    【解决方案1】:

    我不熟悉 python,但如果我得到了你想要的,这里是 SQL 查询:

    SELECT a.id as action_id, timestamp, 
    v.id as version, foo_id, foo_zab
    FROM action a
    JOIN foo_version v 
    ON ( v.action_id IN
      ( 
        SELECT MAX(inner_v.action_id)
        FROM foo_version inner_v 
        WHERE a.id >= inner_v.action_id
        GROUP BY inner_v.foo_id
      )                      
    )
    JOIN foo ON ( foo.id = v.foo_id ) 
    ORDER BY a.id, version
    

    它将为您提供与每个版本的数据重复的每个操作行 这是SQL fiddle demo

    【讨论】:

      猜你喜欢
      • 2012-02-13
      • 1970-01-01
      • 2018-09-17
      • 2019-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多