SqlAlchemy:多列的不重复计数

问题描述 投票:15回答:3

我做不到:

>>> session.query(
        func.count(distinct(Hit.ip_address, Hit.user_agent)).first()
TypeError: distinct() takes exactly 1 argument (2 given)

我可以:

session.query(
        func.count(distinct(func.concat(Hit.ip_address, Hit.user_agent))).first()

哪个很好('页面加载量'数据库表中的唯一身份用户数)。

在一般情况下,这是不正确的,例如下表的计数将为1而不是2:

 col_a | col_b
----------------
  xx   |  yy
  xxy  |  y

有什么方法可以生成以下SQL(至少在postgresql中有效)?

SELECT count(distinct (col_a, col_b)) FROM my_table;
postgresql count sqlalchemy distinct aggregate-functions
3个回答
8
投票

看起来像sqlalchemy exclude()仅接受一个列或表达式。

另一种解决方法是使用group_bycount。这应该比使用两列的concat更有效-如果按索引存在,则按数据库分组可以使用索引:

session.query(Hit.ip_address, Hit.user_agent).\
    group_by(Hit.ip_address, Hit.user_agent).count()

生成的查询看起来仍然与您询问的内容不同:

SELECT count(*) AS count_1 
FROM (SELECT hittable.user_agent AS hittableuser_agent, hittable.ip_address AS sometable_column2 
FROM hittable GROUP BY hittable.user_agent, hittable.ip_address) AS anon_1

20
投票

distinct()附加到查询对象时接受多个参数:

session.query(Hit).distinct(Hit.ip_address, Hit.user_agent).count()

它应该生成类似:

SELECT count(*) AS count_1
FROM (SELECT DISTINCT ON (hit.ip_address, hit.user_agent)
hit.ip_address AS hit_ip_address, hit.user_agent AS hit_user_agent
FROM hit) AS anon_1

甚至更接近您想要的。


0
投票

可以使用tuple_()构造产生确切的查询:

tuple_()
© www.soinside.com 2019 - 2024. All rights reserved.