我做不到:
>>> 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中有效)?
SELECT count(distinct (col_a, col_b)) FROM my_table;
答案 0 :(得分:15)
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
甚至更接近你想要的东西。
答案 1 :(得分:7)
看起来sqlalchemy distinct()只接受一个列或表达式。
另一种方法是使用group_by
和count
。这应该比使用两列中的concat
更有效 - 如果它们存在,group by database将能够使用索引:
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
答案 2 :(得分:6)
可以使用tuple_()
构造产生确切的查询:
session.query(
func.count(distinct(tuple_(Hit.ip_address, Hit.user_agent)))).scalar()