2016-03-29 8 views
3

条件に一致する行がない場合、カウント値0を取得しようとしています。グループからの選択でカウント(*)値0を得る方法

私は大きなテーブルを持っています。しかし、私はそれが私が欲しいものを説明するように切り捨てられたテーブルを掲示しています。

表1:

**name year title** 
name1 2008 title1 
name2 2009 title2 
name3 2010 title1 
name1 2008 title2 
name4 2009 title1 
name2 2008 title2 

私は年= 2008すべての名前の行の数を示したいと思います。だから、もし2008年の行がないならば。名前とそのカウント0が表示されます。

出力は次のようになります。

**name count** 
    name1 2 
    name2 1 
    name3 0 
    name4 0 

回避策:

select p.name,(select count(*) 
       from table1 b 
       where b.name=p.name) as count 
from table1 p 
where p.year=2008; 

いくつかのより多くを試してみました。しかし、彼らのどれも働いていませんでした。

答えて

7

はこれを試してみてください:

select p.name, 
     count(case when p.year=2008 then 1 end) as count 
from table1 p 
group by p.name 

条件付きp.name値のyear=2008発生をカウントするようにクエリが条件付き集約を使用しています。

+0

感謝。 :)あなたは私の半日を救った!私はこの最初の半日を無駄にしました。しかし、SQLでいくつかの新しいことを学びました。 – sailesh

1

また、のDECODEを使用することもできます。もちろん、ケースはかなり明確で冗長です。与えられたデータセットについて

SELECT NAME, 
     COUNT(DECODE(YEAR, 2008, 1)) COUNT 
FROM your_table 
GROUP BY NAME 
ORDER BY COUNT DESC; 

例えば、

SQL> WITH sample_data AS(
    2 SELECT 'name1' NAME, 2008 YEAR FROM dual UNION ALL 
    3 SELECT 'name2' NAME, 2009 YEAR FROM dual UNION ALL 
    4 SELECT 'name3' NAME, 2010 YEAR FROM dual UNION ALL 
    5 SELECT 'name1' NAME, 2008 YEAR FROM dual UNION ALL 
    6 SELECT 'name4' NAME, 2009 YEAR FROM dual UNION ALL 
    7 SELECT 'name2' NAME, 2008 YEAR FROM dual 
    8 ) 
    9 --end of sample_Data mimicking real table 
10 SELECT NAME, 
11   COUNT(DECODE(YEAR, 2008, 1)) COUNT 
12 FROM sample_data 
13 GROUP BY NAME 
14 ORDER BY COUNT DESC; 

NAME  COUNT 
----- ---------- 
name1   2 
name2   1 
name4   0 
name3   0 

SQL> 
+0

@saileshだから?実際のテストケースを構築するために使用されたWITH句のsample_dataと混同していますか? –

+0

私はこれに新しいです。ごめんなさい! – sailesh

+0

@sailesh問題はありません。 WITH句を使用して、sample_dataが模倣している静的テーブルと同じように、サンプルのテストケースを作成します。 –

1

、@GiorgosBetsosは良い答えを与えます。

さらに一般化された答えは、2つのテーブルを使用します。データ(ファクトテーブル)の1つ、名前リスト(ディメンションテーブル)の1つ。これにより、次のような構造が得られます。

SELECT 
    person_dimension.name, 
    COUNT(fact_table.title) 
FROM 
    person_dimension 
LEFT JOIN 
    fact_table 
     ON fact_table.person_id = person_dimension.id 
     AND fact_table.year = 2008 
GROUP BY 
    person_dimension.name 

このようにして、データ構造を正規化することも強制されます。できるだけ多くのテーブルにすべてのデータを保存することが魅力的かもしれませんが、その方法はリレーショナルデータベースに多くの苦痛をもたらします。ファクトとディメンションを分離する方がはるかに標準的です。

ここで追加される利点の1つは、名前のサブセットに非常に簡単にフィルタリングできることです。例えば....

SELECT 
    person_dimension.name, 
    COUNT(fact_table.title) 
FROM 
    person_dimension 
LEFT JOIN 
    fact_table 
     ON fact_table.person_id = person_dimension.id 
     AND fact_table.year = 2008 
WHERE 
    person_dimension.country = 'Unknown' 
GROUP BY 
    person_dimension.name 
-1
select p.name, 
    count(*) over(partition by name) as cnt 
    from table1 p where year=2008 
    order by cnt; 
+0

件数(p.year)? OPは、2008年のROWSを数えたかった。 – mathguy

+0

まだ何か@mathguy –

+0

これは、OPが要求したように、テーブルにyear = 2008の行を持たない「名前」を返しません。投稿する前にソリューションをテストしますか?それは良い習慣です。乾杯! – mathguy

関連する問題