2013-05-24 13 views
10

kann ich nicht tun:sqlalchemy: Zählt eindeutig über mehrere Spalten

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

ich tun kann:

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

was in Ordnung ist (Anzahl der Unique User in einem 'Pageload' db-Tabelle).

Dies ist im allgemeinen Fall, z. gibt einen Zählwert von 1 anstelle von 2 für die folgende Tabelle:

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

Gibt es eine Möglichkeit die folgenden SQL (die in postgresql mindestens gültig ist) zu erzeugen?

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

Antwort

4

Sieht aus wie sqlalchemy distinct() akzeptiert nur eine Spalte oder einen Ausdruck.

Ein anderer Weg ist, group_by und count zu verwenden. Dies sollte effizienter sein als concat von zwei Spalten mit - mit der Gruppe von Datenbankindizes zu verwenden, wäre in der Lage, wenn sie existieren:

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

generierte Abfrage noch anders aussehen würde, von dem, was Sie gefragt:

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

Sehr gut. Ich hätte nicht an diesen Ansatz gedacht, da es viel in SQL schreibt. In SQLA ist es sehr einfach! – EoghanM

11

distinct() nimmt mehr als ein Argument, wenn auf die Abfrage-Objekt angehängt:

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

Es ist etwas erzeugen sollte wie:

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 

das ist sogar ein bisschen näher an dem, was Sie wollten.

Verwandte Themen