2017-12-11 5 views
0

私はシステム内のすべてのユーザーを含むユーザーテーブルと、システム内のユーザーが実行したすべての操作を含む他のテーブルを持っています。取得私は、ユーザーがアクションを数えることができると私は一人のユーザのための任意のアクションが00を含む数が異なる行の2つのテーブルを結合するpostgres

私の二つのテーブルを取得していない場合は、クエリです:

Users Table: 

Name  Place 
---------------------- 
James  Supermarket 
Alex  Bank 
Ignatius BookShop 

Action table: 

Name Action 
-------------------- 
James Buy 
James Buy 
Alex Complaint 
Alex Buy 
Alex Buy 

を、私はこのような何かをしたいです

Name  Transactions Place 
------------------------------- 
James  2    Supermarket 
Alex  3    Bank 
Ignatius 0    BookShop 

私はtryied:

SELECT users.name, 
    (SELECT Count(action.name) 
    FROM action, 
      users 
    WHERE action.name = users.name 
    GROUP BY action.name) 
    users.place 
FROM 
action, 
users 
WHERE action.name = users.name 

しかし、いつも私は、このエラーを与えている:

ERROR: more than one row returned by a subquery used as an expression SQL state: 21000

それを行う方法についての任意のアイデアを?

答えて

1

決して使用コンマ。常に正しい、明示的なJOIN構文を使用してください。それはあなたが相関サブクエリを使用したい場合は、任意のは、このクエリのすべてで加入する必要はありません、言った:

SELECT u.name, 
     (SELECT Count(*) 
     FROM action a 
     WHERE a.name = u.name 
     ) as cnt, 
     u.place 
FROM users u; 

は、パフォーマンスのために、あなたはaction(name)にインデックスをしたいです。このようなインデックスでは、これはleft joingroup byを使用する代替バージョンよりも高速かもしれません。

注:

  • すべてのテーブルは、テーブル名の省略形です表の別名を持ちます。
  • このバージョンのクエリには、結合は必要ありません。
  • いいえgroup byサブクエリにあります。
  • 外部クエリでは、いいえwhere句が必要です。
+0

あなたのソリューションは正常に動作しますが、遅いですが、それは良いことです。どうもありがとう –

2

あなたが最初に参加し、その結果にしてグループを適用し、左の作業を行う必要があります

SELECT 
    u.name 
, COUNT(a.name) AS Transactions 
, u.place 
FROM users u 
LEFT OUTER JOIN action a ON a.name = u.name 
GROUP BY u.name, u.place 

左が参加し、それがactionテーブルに関連するトランザクションを持っていない場合でも、ユーザー・レコードが破棄されていないことを保証します。 FROM句の

+0

ハイテクをまとめた後、参加しないが、それがうまく働いていますが、私は私が削除した場合、それはgivinigされ、によってグループにu.placeを含めたくない@dasblinkenlight私は含めなければならないと言ったエラー、私は含めることはできません。どうすればいい? –

+0

@JoanTriay 'name'がユーザを一意に識別していると仮定すると、' group by 'で 'place'を使用することに違いはありません。両方のフィールドが同じテーブルから来て、フィールド(name) 。 – dasblinkenlight

0

以前の回答と同様に、左の結合が表示されます。 あなたは結果に場所を含めたい場合は、左が

SELECT a.name, 
     ISNULL(b.cnt, 0) AS Transactions, 
     a.place 
FROM users a 
LEFT JOIN 
    (SELECT name, 
      Count(name) cnt 
    FROM action 
    GROUP BY name) b 
ON a.name = b.name 
関連する問題