2013-05-24 26 views
10

:私は行うことができます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() 

結構です( 'pageload' 内のユニークユーザー数DBテーブル)。

これは一般的なケースでは正しくありません。次の表の1の代わりに、2のカウントを与える:

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

は(少なくともPostgreSQLの有効です)以下のSQLを生成する方法はありますか?

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

答えて

4

sqlalchemyのように見えます。distinct()は1つの列または式しか受け入れません。

別の方法では、group_bycountを使用することです。

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つの列の concatを使用するよりも効率的でなければなりません

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

それはのようなものを生成する必要があります:クエリオブジェクトに追加するとき

+0

非常に良好です。 SQLでは多くのタイピングが行われているので、このアプローチは考えられませんでした.SQLAでは非常に簡単です! – EoghanM

11

distinct()は、複数の引数を受け取り

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 

これはあなたが望むものにさらに近いものです。

関連する問題