python - 使用 SQLAlchemy 计算结果集中包含的值实例

标签 python mysql orm sqlalchemy

如果问题标题没有描述性/措辞不当,我们深表歉意。

我希望能够计算在满足特定条件的行中出现特定值的实例数。考虑以下两个表,queuesqueue_contents

队列表:

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

queue_contents 表:

+-----+----------+--------+
| 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 |
+----------+------------+-------------+-----------------------+

我不知道如何计算 queue_contents.foo_id WHERE queue_contents.queue_id == 3 中出现的 foo_id 的实例数

获取每个队列的 total_count 已经足够简单了,但是在设置子查询和条件时,我感到很困惑。我觉得解决方案涉及使用子查询并计算该子查询中出现的 foo_id 的数量,但我无法让它工作。我不会包括我尝试过的以下查询的 maaaany 迭代,尽管这会让您了解我所处的轨道:

foo_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')

最佳答案

如果 queue_id 组不包含 foo_id 重复项,您可以使用 LEFT JOIN:

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)

如果他们这样做,您可以使用包含在 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 的行数这一事实。

关于python - 使用 SQLAlchemy 计算结果集中包含的值实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51527075/

相关文章:

python - 如何找到哪个库阻止更新 conda 中的包?

mysql - 在 node.js 中连接 ENOENT/var/run/mysqld/mysqld.sock 时出错

java - Hibernate 模板中的动态表创建

mysql - 从sql查询中的url获取id

c# - 从方法体内获取表达式树

python - Django 按小时/天分组

node.js - Sequelize 无法连接到 MySql

python - 用 python 更新我的字典

python - 错误 UnboundLocalError : local variable 'currentpl' referenced before assignment:

python - 使用 subprocess.check_output() 在 python 中搜索文件