複数カラム - mysql 集計関数




MySQLのすべての行のcount(*)の合計 (6)

私は、 group by 持つすべての行の count(*) 値の合計が欲しい sum() クエリを使い続けています。

これがクエリです:

select
    u.user_type as user,
    u.count,
    sum(u.count)
FROM
(
select 
    DISTINCT
    user_type,
    count(*) as count
FROM
    users
where
    (user_type = "driver" OR user_type = "passenger")
GROUP BY
    user_type
) u;

電流出力:

----------------------------------
|  user     |  count     |  sum  |
----------------------------------
| driver    | 58         |  90   |
----------------------------------

期待される出力:

----------------------------------
|  user     |  count     |  sum  |
----------------------------------
| driver    | 58         |  90   |
| passenger | 32         |  90   |
----------------------------------

クエリから sum(u.count) を削除すると、出力は次のようになります。

--------------------------
|  user     |  count     |
--------------------------
| driver    | 58         |
| passenger | 32         |
--------------------------

これを試して。 インラインビューは全体の合計を取得します。

SELECT a.user_type, 
       count(*) AS count,
       b.sum  
FROM   users a
JOIN (SELECT COUNT(*) as sum 
      FROM users 
      WHERE user_type IN ("driver","passenger" )
     ) b ON TRUE
WHERE  a.user_type IN ("driver","passenger" ) 
GROUP  BY a.user_type;

これを試して:

WITH SUB_Q AS (
  SELECT USER_TYPE, COUNT (*) AS CNT
  FROM USERS
  WHERE USER_TYPE = "passenger" OR USER_TYPE = "driver"
  GROUP BY USER_TYPE
), 
SUB_Q2 AS (
  SELECT SUM(CNT) AS SUM_OF_COUNT
  FROM SUB_Q
)
SELECT A.USER_TYPE, A.CNT AS COUNT, SUB_Q2 AS SUM
FROM SUB_Q JOIN SUB_Q2 ON (TRUE);

私はpostgresqlの方言を使いましたが、あなたは簡単に副問い合わせに変更することができます。


単純に SUM() OVER()COUNT(*) 組み合わせることができます。

SELECT user_type, COUNT(*) AS cnt, SUM(COUNT(*)) OVER() AS total
FROM  users WHERE user_type IN ('driver', 'passenger') GROUP BY user_type;

db <>フィドルデモ

出力:

+------------+------+-------+
| user_type  | cnt  | total |
+------------+------+-------+
| passenger  |  58  |    90 |
| driver     |  32  |    90 |
+------------+------+-------+

私は尋ねたくなるでしょう。 DBレベルでこれを必要としていますか?

純粋にデータベース層で作業しているのでなければ、これらの結果の処理はすべてアプリケーション層に組み込まれており、おそらく何らかの形で結果をループ処理する必要があります。

それは実行するのがより簡単で、より簡単で、そしてより読みやすいかもしれません

  SELECT user_type,
         COUNT(*) AS count
    FROM users
   WHERE user_type IN ("driver", "passenger")
GROUP BY user_type

..そして単にアプリケーション層の合計カウントを合計する

Juanが別の回答で指摘したように、GROUP BYによって結果の各行が異なることが保証されるため、DISTINCTは冗長です。

Juanのように、私はuser_typeの方が読みやすいと思うので、ここではOR条件よりもINを好む。 将来さらにAND条件を組み合わせた場合に混乱が生じる可能性も低くなります。

余談ですが、私はユーザータイプの名前 "driver"と "passenger"を別のuser_typesテーブルに移動し、それらをusersテーブルのID列で参照することを検討します。

NB DBレベルでこれが絶対に必要な場合は、Paulの優れた選択肢の1つ、またはTom Macによって提案されたCROSS JOINアプローチ、そしてJuanが彼の2番目の提案された解決策を使用することを推奨します。


user-type 最後に group by 句を追加してください。例えば:

select
    u.user_type as user,
    u.count,
    sum(u.count)
FROM
(
select 
    DISTINCT
    user_type,
    count(*) as count
FROM
    users
where
    (user_type = "driver" OR user_type = "passenger")
GROUP BY
    user_type
) u GROUP BY u.user_type;

トムマックは正しくあなたの答えを説明します。 これがあなたがそうすることができるもう一つの方法です。 クエリのパフォーマンスを確認しましたが、1000件のレコードで差が見つかりませんでした

   select user_type,Countuser,(SELECT COUNT(*) 
   FROM users 
   WHERE user_type IN ('driver','passenger ') )as sum from (
   select user_type,count(*) as Countuser from users a
   where a.user_type='driver'
   group by a.user_type
   union
   select user_type,count(*) as Countuser from users b
   where b.user_type='passenger'
   group by b.user_type
   )c
   group by user_type,Countuser






rdbms