web-dev-qa-db-ja.com

countサブクエリ、内部結合、およびグループを使用したクエリ

私は間違いなくSQLの初心者です。私は、Postgresqlで次のテーブル構造を使用して複雑なクエリを作成するために頭を悩ませてきました。

CREATE TABLE reports
(
  reportid character varying(20) NOT NULL,
  userid integer NOT NULL,
  reporttype character varying(40) NOT NULL,  
)

CREATE TABLE users
(
  userid serial NOT NULL,
  username character varying(20) NOT NULL,
)

クエリの目的は、ユーザーごとのレポートタイプの数を取得し、それを1つの列に表示することです。レポートには3つの異なるタイプがあります。

Group-byを使用した単純なクエリで問題は解決しますが、別の行に表示されます。

select count(*) as Amount,
       u.username,
       r.reporttype 
from reports r,
     users u 
where r.userid=u.userid 
group by u.username,r.reporttype 
order by u.username
7
SELECT
  username,
  (
  SELECT 
    COUNT(*)
  FROM reports 
  WHERE users.userid = reports.userid && reports.reporttype = 'Type1'
  ) As Type1,
  (
  SELECT 
    COUNT(*)
  FROM reports 
  WHERE users.userid = reports.userid && reports.reporttype = 'Type2'
  ) As Type2,
  (
  SELECT 
    COUNT(*)
  FROM reports 
  WHERE users.userid = reports.userid && reports.reporttype = 'Type3'
  ) As Type3
FROM
  users
WHERE 
  EXISTS(
    SELECT 
      NULL
    FROM 
      reports
    WHERE 
       users.userid = reports.userid
  )
17
Magnus
SELECT
  u.username,
  COUNT(CASE r.reporttype WHEN 1 THEN 1 END) AS type1Qty,
  COUNT(CASE r.reporttype WHEN 2 THEN 1 END) AS type2Qty,
  COUNT(CASE r.reporttype WHEN 3 THEN 1 END) AS type3Qty
FROM reports r
  INNER JOIN users u ON r.userid = u.userid 
GROUP BY u.username

サーバーのSQLダイアレクトでELSEブランチをCASE式に含める必要がある場合は、すべてのENDの前にELSE NULLを追加します。

7
Andriy M

「ユーザーあたりのレポートタイプの数」を探している場合は、各ユーザーに対して1、2、または3のいずれかの数値(3つの異なるタイプのレポートがある場合)が表示されるはずです。レポートタイプは予期されないため(表示されずにカウントされるだけです)、クエリのSELECT部分​​またはGROUPBY部分のいずれにもレポートタイプは必要ありません。

代わりに、COUNT(DISTINCT r.reporttype)を使用して、各ユーザーが使用するさまざまなレポートタイプの数をカウントします。

SELECT
 COUNT(DISTINCT r.reporttype) as Amount
,u.username
FROM users u 
INNER JOIN reports r
ON r.userid=u.userid 
GROUP BY
 u.username
ORDER BY u.username
0
ajmcp