使用sqlalchemy计算结果集中包含的值的示例数

2admgd59  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(366)

如果问题标题不具有描述性/措辞不当,请道歉。
我希望能够计算满足特定条件的行中出现的特定值的示例数。考虑以下两个表, queues 以及 queue_contents 队列表:

+----+---------+
| id |  name   |
+----+---------+
|  1 | queue A |
|  2 | queue B |
|  3 | queue C |
+----+---------+

队列内容表:

+-----+----------+--------+
| id  | queue_id | foo_id |
+-----+----------+--------+
|  1  |        1 |    10  |
|  2  |        1 |    11  |
|  3  |        1 |    12  |
|  5  |        2 |    20  |
|  6  |        2 |    21  |
|  7  |        2 |    23  |
|  8  |        2 |    24  |
|  9  |        3 |    10  |
|  10 |        3 |    11  |
|  11 |        3 |    20  |
|  12 |        3 |    30  |
+-----+----------+--------+

我想要一个查询,输出以下结果时,我查询 queue_id == 3 ```
+----------+------------+-------------+-----------------------+
| queue_id | queue_name | total_count | contained_in_this_one |
+----------+------------+-------------+-----------------------+
| 1 | queue A | 3 | 2 |
| 2 | queue B | 4 | 1 |
+----------+------------+-------------+-----------------------+

我不知道如何计算 `foo_id` 发生在 `queue_contents.foo_id WHERE queue_contents.queue_id == 3` 这是微不足道的,足以得到 `total_count` 对于每个队列,但当涉及到设置子查询和条件时,我很困惑。我觉得解决方案包括使用子查询并计算 `foo_id` 发生在子查询中的,但我无法使它工作。我不会包含我尝试过的以下查询的任何迭代,尽管这会让您了解我所处的轨道:

## 此查询中的foo\u id

sq = db_session.query(Foo.id.label('foo_id'))
.join(QueueContent, QueueContent.foo_id == Foo.id)
.filter(QueueContent.queue_id == 3)
.subquery('sq')

foo_alias = aliased(Foo)

q2 = db_session.query(func.count(Foo.id).label('total_in_task'),
func.count(foo_alias.id).label('count_in_this_task'),
Queue.id.label('queue_id'),
Queue.name.label('queue_name'))
.join(foo_alias, foo_alias.id == Foo.id)
.join(QueueContent, QueueContent.foo_id == Foo.id)
.join(Queue, Queue.id == QueueContent.queue_id)
.filter(Queue.id != 3)
.group_by('queue_name', 'queue_id')

dced5bon

dced5bon1#

如果 queue_id 组不包含 foo_id 重复,可以使用左连接:

qc2 = aliased(QueueContent)

session.query(QueueContent.queue_id,
              func.count(),
              func.count(qc2.foo_id)).\
    outerjoin(qc2, and_(qc2.queue_id == 3,
                        qc2.foo_id == QueueContent.foo_id)).\
    filter(QueueContent.queue_id != 3).\
    group_by(QueueContent.queue_id)

如果是这样,则可以使用 Package 在nullif中的exists子查询表达式(或转换为整数并求和):

qc2 = aliased(QueueContent)

sq = session.query(qc2).\
    filter_by(queue_id=3, foo_id=QueueContent.foo_id).\
    exists()

session.query(QueueContent.queue_id,
              func.count(),
              func.count(func.nullif(sq, False))).\
    filter(QueueContent.queue_id != 3).\
    group_by(QueueContent.queue_id)

这两个变体都使用这样一个事实:count(expression)生成expression值不为null的行数。

相关问题