SqlAlchemy: количество отдельных над несколькими столбцами
Я не могу:
>>> 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()
Что хорошо (количество уникальных пользователей в таблице db pageload).
Это неверно в общем случае, например. даст счет 1 вместо 2 для следующей таблицы:
col_a | col_b
----------------
xx | yy
xxy | y
Есть ли способ создать следующий SQL (который действителен в postgresql)?
SELECT count(distinct (col_a, col_b)) FROM my_table;
Ответы
Ответ 1
Похоже, sqlalchemy distinct() принимает только один столбец или выражение.
Другой способ - использовать group_by
и count
. Это должно быть более эффективным, чем использование 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
Ответ 2
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
который даже немного ближе к тому, что вы хотели.