2013-05-24 22 views
10

nie mogę zrobić:sqlalchemy: Ilość odrębne nad wieloma kolumnami

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

mogę zrobić:

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

Który jest w porządku (liczba unikalnych użytkowników w 'pageload' db stół).

W ogólnym przypadku nie jest to poprawne, np. daje liczbę 1 zamiast 2 do poniższej tabeli:

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

Czy istnieje jakiś sposób, aby generować następujące SQL (co jest ważne w PostgreSQL przynajmniej)?

SELECT count(distinct (col_a, col_b)) FROM my_table; 

Odpowiedz

4

Wygląda na to, że sqlalchemy distinct() akceptuje tylko jedną kolumnę lub wyrażenie.

Innym sposobem jest użycie group_by i count. To powinno być bardziej efektywne niż przy użyciu concat dwóch kolumnach - z grupy przez bazy danych będzie mógł używać indeksów jeśli one istnieją:

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

Wygenerowane zapytanie będzie nadal wyglądać inaczej od tego, co pytasz o:

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

Bardzo dobrze. Nie pomyślałbym o tym podejściu, ponieważ jest to dużo pisania w SQL ... kiedy jest w SQLA, to bardzo proste! – EoghanM

11

distinct() przyjmuje więcej niż jeden argument kiedy dołączono do obiektu zapytań:

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

należy wytwarzać podobnie jak:

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 

który jest nawet trochę bliżej tego, co chciałeś.

Powiązane problemy