同じselectステートメントでcountとgroup byを使用する方法


223

グループ化されたSQL選択クエリがあります。group byステートメントの後のすべてのレコードをカウントしたい。これをSQLから直接行う方法はありますか?たとえば、さまざまな町とユーザーの総数を選択するユーザーのテーブルがあるとします。

select town, count(*) from user
group by town

すべての町を含む列と、すべての行のユーザー数を含む列が必要です。

3つの町と合計58人のユーザーがいる場合の結果の例は次のとおりです。

Town         Count
Copenhagen   58
NewYork      58
Athens       58

あなたはあなたの結果セットが2つのカウントを持つようにしたいということを意味します。
レスリー

2
つまり、各町に1つの行が必要であり、各行の列2にはすべてのユーザーの合計数が含まれていますか?したがって、列2の各行の値は同じですか?編集してサンプルデータと必要な出力を含めると、希望どおりの結果を得ることができます。
AakashM 2010

あなたは正しいAakashMです!編集しました。
Stavros、2010


1
読者への警告:ほとんどの回答は、更新されたクエリに対する回答を提供できません。
リックジェームズ

回答:


271

これはあなたが望むことをします(町のリスト、それぞれのユーザーの数):

select town, count(town) 
from user
group by town

あなたは、ほとんど使用することができ、集計関数を使用した場合GROUP BY

更新(質問とコメントの変更後)

ユーザー数の変数を宣言し、それをユーザー数に設定して、それで選択できます。

DECLARE @numOfUsers INT
SET @numOfUsers = SELECT COUNT(*) FROM user

SELECT DISTINCT town, @numOfUsers
FROM user

それはまさにOPが書いたものですか?nvm、私はあなたの違いを見ます、あなたは町ではなく* ....を数えています
レスリー

@Leslie-2つのクエリの間に違いはありません。それらは同じ結果セットを返します。私はただの使用が嫌い*です... OPは彼自身の質問に答えましたが、それをテストすることすらしなかったようです。それが正しいことを検証しているだけです:) fredosaurus.com/notes-db/select/groupby.html
Oded

ここでもない何私が望んで、...これが最善の解決策であると思われ;)おかげで
スタブロス

149

使用できますCOUNT(DISTINCT ...)

SELECT COUNT(DISTINCT town) 
FROM user

3
チャームとして機能します...主な答えを選択する必要があります..これは良くないいくつかのプローブを除きます
ビクター

2
WHERE句にCOUNT(DISTINCTタウン)を入れると、それらが意味すると思います。これは集約関数であり、HAVING句で指定する必要があるためです。SELECT COUNT(DISTINCTタウン)が暗黙のGROUP BYに変わるため、このSQLクエリは誤解を招く可能性があります。COUNTとDISTINCTの両方のキーワードにより、各キーワード自体も暗黙的にグループ化されます。
A. Greensmith 2016年

ありがとう。賛成票。正確に何が必要か-1つの演算でグループ化+カウントし、結果として単一の行を取得します。
Green

たわごと..それが可能であることを知りませんでした!
Hugo S. Mendes、

1
@milkovsky-削除する必要はありません。この質問と多くの回答が2つの異なる問題の解決に分岐していることに私はただ苛立ちを感じます。答えは2つの点で異なります。town列がないことと、それCOUNTsが間違っていることです(ユーザーではなく町)。
リックジェームズ

37

もう1つの方法は次のとおりです。

/* Number of rows in a derived table called d1. */
select count(*) from
(
  /* Number of times each town appears in user. */
  select town, count(*)
  from user
  group by town
) d1

5
それ以外の場合はmysqlで機能しないエイリアスが必要です。select count(*)from()agr
amas

4

Oracleでは、分析関数を使用できます。

select town, count(town), sum(count(town)) over () total_count from user
group by town

他のオプションはサブクエリを使用することです:

select town, count(town), (select count(town) from user) as total_count from user
group by town

最後の1が仕事だろうが、私は他の解決策があるかどうかを確認したかったようなもの...
スタブロス

また、最初の(分析関数)オプションを使用できませんか?どのデータベースプラットフォームを使用していますか?
Tommi、

@Stavros:最後の1つは遅い
Michael Buen

4

カウントで並べ替える場合(簡単なように聞こえますが、その方法のスタックで答えが見つからない場合)、次のようにできます。

        SELECT town, count(town) as total FROM user
        GROUP BY town ORDER BY total DESC

4

削除されていない10の回答。ほとんどは、ユーザーが要求したことを行いません。ほとんどの回答は、質問を町に合計58人ではなく58人いると誤解しています。正しいものでも、最適ではありません。

mysql> flush status;
Query OK, 0 rows affected (0.00 sec)

SELECT  province, total_cities
    FROM       ( SELECT  DISTINCT province  FROM  canada ) AS provinces
    CROSS JOIN ( SELECT  COUNT(*) total_cities  FROM  canada ) AS tot;
+---------------------------+--------------+
| province                  | total_cities |
+---------------------------+--------------+
| Alberta                   |         5484 |
| British Columbia          |         5484 |
| Manitoba                  |         5484 |
| New Brunswick             |         5484 |
| Newfoundland and Labrador |         5484 |
| Northwest Territories     |         5484 |
| Nova Scotia               |         5484 |
| Nunavut                   |         5484 |
| Ontario                   |         5484 |
| Prince Edward Island      |         5484 |
| Quebec                    |         5484 |
| Saskatchewan              |         5484 |
| Yukon                     |         5484 |
+---------------------------+--------------+
13 rows in set (0.01 sec)

SHOW session status LIKE 'Handler%';

+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_commit             | 1     |
| Handler_delete             | 0     |
| Handler_discover           | 0     |
| Handler_external_lock      | 4     |
| Handler_mrr_init           | 0     |
| Handler_prepare            | 0     |
| Handler_read_first         | 3     |
| Handler_read_key           | 16    |
| Handler_read_last          | 1     |
| Handler_read_next          | 5484  |  -- One table scan to get COUNT(*)
| Handler_read_prev          | 0     |
| Handler_read_rnd           | 0     |
| Handler_read_rnd_next      | 15    |
| Handler_rollback           | 0     |
| Handler_savepoint          | 0     |
| Handler_savepoint_rollback | 0     |
| Handler_update             | 0     |
| Handler_write              | 14    |  -- leapfrog through index to find provinces  
+----------------------------+-------+

OPのコンテキストでは:

SELECT  town, total_users
    FROM       ( SELECT  DISTINCT town  FROM  canada ) AS towns
    CROSS JOIN ( SELECT  COUNT(*) total_users  FROM  canada ) AS tot;

からの行は1つしかないためtotCROSS JOINは他の場合ほど大きくはありません。

通常のパターンはのCOUNT(*)代わりですCOUNT(town)。後者townは、nullでないかどうかのチェックを意味します。これは、このコンテキストでは不要です。


2

Milovovskyが言ったように、COUNT内でDISTINCTを使用できます

私の場合:

select COUNT(distinct user_id) from answers_votes where answer_id in (694,695);

これは、1つのカウントと同じuser_idと見なされる回答投票のカウントをプルします


2

私はこれがSQL Serverの古い投稿であることを知っています:

select  isnull(town,'TOTAL') Town, count(*) cnt
from    user
group by town WITH ROLLUP

Town         cnt
Copenhagen   58
NewYork      58
Athens       58
TOTAL        174

5
古い投稿に答えることは何の問題もありません。ただし、コードの説明とコード自体を含めてください。
シェルバク2016年

MySQLでの(のIFNULL代わりにISNULL)は、町ごとに異なる数値になります。ユーザーは合計が必要でした。質問によると、174ではなく58が合計です。
リックジェームズ


1

カウントオプション付きのすべてのクエリを選択を使用したい場合は、これを試してください...

 select a.*, (Select count(b.name) from table_name as b where Condition) as totCount from table_name  as a where where Condition

このコードスニペットをありがとうございます。このコードスニペットは、制限された即時のヘルプを提供する可能性があります。適切な説明は、なぜこれが問題の優れた解決策であるを示すことにより、長期的な価値を大幅に改善し、他の同様の質問を持つ将来の読者にとってより有用になるでしょう。回答を編集して、仮定を含めて説明を追加してください。
Toby Speight 2017

0

次のコードを試してください:

select ccode, count(empno) 
from company_details 
group by ccode;

私たちはどのように多くの現代カルクの総従業員一人ひとりCCODE(会社コード)の例では見つけるために、このコードを使用します。count(EMPNO)がCCODE 1のための1839で、カウント(EMPNO)がCCODE 47のための9421です
balajibran
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.