Postgresql SqlAlchemy:多列上的不同计数

Postgresql SqlAlchemy:多列上的不同计数,postgresql,count,sqlalchemy,distinct,aggregate-functions,Postgresql,Count,Sqlalchemy,Distinct,Aggregate Functions,我做不到: >>> 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_ag

我做不到:

>>> 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()
这很好(“pageload”db表中唯一用户的计数)

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

 col_a | col_b
----------------
  xx   |  yy
  xxy  |  y
有没有办法生成以下SQL(至少在postgresql中有效)


看起来sqlalchemy distinct()只接受一个列或表达式

另一种方法是使用
groupby
count
。这应该比使用两列的
concat
更有效-使用group by数据库可以使用索引(如果确实存在):

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

它甚至更接近您想要的内容。

可以使用以下构造生成精确的查询:

session.query(
    func.count(distinct(tuple_(Hit.ip_address, Hit.user_agent)))).scalar()

很好。不会想到这种方法,因为在SQL中需要大量键入。。在SQLA中,这非常简单!这会在所有列上生成一个独特的select,而不仅仅是添加的列作为参数。相反,您需要执行查询(Hit.ip\u address,Hit.user\u agent),然后SQLA会正确处理它。
session.query(
    func.count(distinct(tuple_(Hit.ip_address, Hit.user_agent)))).scalar()