2013-05-24 41 views
10

tôi không thể làm:SQLAlchemy: đếm rõ rệt trên nhiều cột

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

tôi có thể làm:

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

nào là tốt (đếm người dùng duy nhất trong một 'pageload' db bảng).

Điều này không đúng trong trường hợp chung, ví dụ: sẽ cung cấp cho một số trong tổng số 1 thay vì 2 cho bảng sau:

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

Có cách nào để tạo ra SQL sau đây (có giá trị trong postgresql ít nhất)?

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

Trả lời

4

Có vẻ như sqlalchemy distinct() chỉ chấp nhận một cột hoặc biểu thức.

Một cách khác là sử dụng group_bycount. Điều này sẽ có hiệu quả hơn so với sử dụng concat của hai cột - với nhóm bởi cơ sở dữ liệu sẽ có thể sử dụng chỉ số nếu họ tồn tại:

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

truy vấn tạo vẫn sẽ trông khác với những gì bạn được hỏi về:

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

Rất tốt. Sẽ không có suy nghĩ của phương pháp này vì nó rất nhiều đánh máy khi trong SQL .. khi trong SQLA, nó rất dễ dàng! – EoghanM

11

distinct() chấp nhận nhiều hơn một đối số khi gắn vào đối tượng truy vấn:

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

Nó sẽ tạo ra một cái gì đó như:

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 

thậm chí còn gần hơn với những gì bạn muốn.

Các vấn đề liên quan