Count()で条件を指定することは可能ですか?


391

で条件を指定することはできますCount()か?たとえば、[位置]列に「マネージャー」が含まれている行のみをカウントしたいと思います。

countステートメントでそれをしたいのですが、は使用しませんWHERE。ManagerとOtherの両方を同じSELECTように数える必要があるので、私はそれについて尋ねています(この例では、このようなCount(Position = Manager), Count(Position = Other))ものWHEREは役に立たないのです)。


4
すべての*ユーザーにブー、Count(SomeColumnInYourTable)where Position = 'Manager'
Mark Dickinson

6
@マーク:最近のすべてのデータベースでは、これは何の違いもありません。
Philippe Leybaert

5
@Mark&Philippe:実際に大きな違いを生むことができます。フィールドがnull可能であり、インデックスが作成されていない場合、クエリはテーブル内のすべてのレコードを操作する必要があるため、count(*)とcount(field)を使用すると、異なる結果と異なるパフォーマンスが得られます。
Guffa

4
count(*)とcount(x)の実行計画を何年も分析してきましたが、これまでのところ、パフォーマンスの違いを示すものは1つもありません。だからこそ、違いのあるクエリの例を見たいのです。
フィリップレイバート

3
@Matthew:私たちは話していないSELECT *が、SELECT COUNT(*)全く別の獣です、。
フィリップレイバート

回答:


663

クエリ自体をwhere句で制限できない場合は、count集計がnull以外の値のみをカウントするという事実を使用できます。

select count(case Position when 'Manager' then 1 else null end)
from ...

sum同様の方法で集計を使用することもできます。

select sum(case Position when 'Manager' then 1 else 0 end)
from ...

フィールドが整数であり、nullに一致させたい場合はどうなりますか。この方法では機能しませんselect count(case IntegerField when 'NULL' then 1 else null end)from
Faizan

2
@ファイザンnullは特別です。使用case when IntegerField is null then ...
Peet Brits

:ブールフィールドで作業するときは、この使用することができますSUM(CONVERT(int, IsManager))
Simon_Weaver

2
SQL Serverはelse nullfor caseステートメントを暗黙指定するため、count()例では10文字短くすることができます(スペースを数える場合)。
マイケル-クレイシャーキーは

212

他の値も集計しているため、返される行を制限したくない場合は、次のようにできます。

select count(case when Position = 'Manager' then 1 else null end) as ManagerCount
from ...

同じ列内にマネージャー、スーパーバイザー、チームリーダーの値があり、それぞれの数を次のように取得できるとします。

select count(case when Position = 'Manager' then 1 else null end) as ManagerCount,
    count(case when Position = 'Supervisor' then 1 else null end) as SupervisorCount,
    count(case when Position = 'Team Lead' then 1 else null end) as TeamLeadCount,
from ...

3
これは、指定する必要すらありません@RedFilter elseだけで、一部をendその直後1
Denis Valeev 2010

7
@Denis:正解elseです。ケースステートメントの結果をより適切に文書化するため、特に初心者のSQL開発者にとって、私はしばしばinのままにします。簡潔にするために、この場合は削除できます。
RedFilter

30

@Guffaの答えは素晴らしいです。多分IFステートメントでよりクリーンであることを指摘してください

select count(IF(Position = 'Manager', 1, NULL)) as ManagerCount
from ...

21

意味に依存しますが、意味の他の解釈は、特定の値を持つ行をカウントしたいが、SELECTそれらの行だけに制限したくない場合です...

次のように使用SUM()する代わりに、次のように句を使用してそれを実行しますCOUNT()

SELECT SUM(CASE WHEN Position = 'Manager' THEN 1 ELSE 0 END) AS ManagerCount,
    SUM(CASE WHEN Position = 'CEO' THEN 1 ELSE 0 END) AS CEOCount
FROM SomeTable

13

SQL 2005以降を使用している場合は、ピボットキーワードも使用できます。

詳細およびTechnetから

SELECT *
FROM @Users
PIVOT (
    COUNT(Position)
    FOR Position
    IN (Manager, CEO, Employee)
) as p

テストデータセット

DECLARE @Users TABLE (Position VARCHAR(10))
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('CEO')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')

5

これだけですか?

SELECT Count(*) FROM YourTable WHERE Position = 'Manager'

もしそうなら、それはうまくいきます!


1
編集は、彼がWHERE句で行を制限したくないことを示しています
KinSlayerUY

4

私はこれが本当に古いことを知っていますが、私はそのNULLIFようなシナリオのトリックが好きで、今のところ欠点はありません。コピー&貼り付けの例をご覧ください。これはあまり実用的ではありませんが、使用方法を示しています。

NULLIF パフォーマンスにわずかなマイナスの影響を与える可能性がありますが、それでもサブクエリよりも高速であるはずです。

DECLARE @tbl TABLE ( id [int] NOT NULL, field [varchar](50) NOT NULL)

INSERT INTO @tbl (id, field)
SELECT 1, 'Manager'
UNION SELECT 2, 'Manager'
UNION SELECT 3, 'Customer'
UNION SELECT 4, 'Boss'
UNION SELECT 5, 'Intern'
UNION SELECT 6, 'Customer'
UNION SELECT 7, 'Customer'
UNION SELECT 8, 'Wife'
UNION SELECT 9, 'Son'

SELECT * FROM @tbl

SELECT 
    COUNT(1) AS [total]
    ,COUNT(1) - COUNT(NULLIF([field], 'Manager')) AS [Managers]
    ,COUNT(NULLIF([field], 'Manager')) AS [NotManagers]
    ,(COUNT(1) - COUNT(NULLIF([field], 'Wife'))) + (COUNT(1) - COUNT(NULLIF([field], 'Son'))) AS [Family]
FROM @tbl

コメントありがとうございます:-)



2

単純なWHERE句を使用して、レコードのカウントのみを選択できると思います。


なぜ反対票を投じるのですか?私が答えた後(または同時にかもしれない)、多くの人々が同様のことを答え、彼らは反対票を獲得しませんでした。/ :(
NawaMan、2009

4
質問は「条件ごとに値をカウントする」ではなく「カウントで条件を指定する」であるため、反対票を獲得します。だからあなたは間違った質問に答えています
Radon8472

3
回答に反対票を投じるのは少し不公平です。回答が書かれたとき、それは質問に対する正しい解決策でした....彼はこの回答の4分後に追加のテキストを追加しました!
Peter

2

これは、各出荷コンテナー内で、基準を満たす総数と数の両方を含むデータセットを取得するために行ったものです。これにより、「サイズ51を超えるX%を超える商品が入っている輸送用コンテナの数」という質問に答えることができます

select
   Schedule,
   PackageNum,
   COUNT (UniqueID) as Total,
   SUM (
   case
      when
         Size > 51 
      then
         1 
      else
         0 
   end
) as NumOverSize 
from
   Inventory 
where
   customer like '%PEPSI%' 
group by
   Schedule, PackageNum


-4

これを使用して、マネージャーの数を取得します

Select Position, count(*) as 'Position Counter'
from your_table 
group by Position 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.