2016-04-26 3 views
2

私は次のようなクエリを持っています。それはcteを使用しています。そのカウントに行が存在しないにもかかわらず、左結合のカウント1が返されますか?

SELECT d.hour, 
     hourkey, 
     range, 
     COUNT(*) as 'count' 
FROM dimhour d 
    LEFT JOIN cte2 
     ON d.hour = cte2.hourkey 
     AND range IS NOT NULL 
WHERE d.hour <= 23 
GROUP BY d.hour, 
     hourkey, 
     range     
ORDER BY d.hour DESC 

これは、このクエリの結果である:cte2

hour hourkey range count 
18  NULL  NULL  1 
17  NULL  NULL  1 
16  NULL  NULL  1 
15  15  99%  15 
14  14  99%  15 
13  13  99%  15 
12  12  99%  15 
11  11  99%  15 
10  10  99%  15 

結果はここに投稿するには大きすぎるが、私はcte2.hourkeyがある時間ことを伝えることができnullcte2内に1つの行がありません。 Hr15の後にcount(*)の正の数を返す可能性のあるものは何もありません。しかし、count(*)は何とかそれらのために1を返します。

なぜこのクエリは存在しない時間にcount(*)を1に戻しますか?どのように削除できますか?

+2

'count(cte2.hourkey)'を試してください。 – Kateract

+0

「0」が返されますが、その行はまだ結果に表示されています。そして私はそれらを取り除く方法を知らない。 – rbhat

+1

次に、ヌル値を表示したくない場合や、間違ってしまった場合は、 'inner'ジョインを使用してください。 – Sherlock

答えて

3

COUNT(*)は、特定のグループ内のすべての行の数を返します(行を含む)。特定の列を数えたい場合は、COUNT(cte2.hourkey)などの列を指定する必要があります。これにより、グループ内のnull以外のレコードがカウントされます。

SELECT d.hour, hourkey, range, COUNT(cte2.hourkey) AS [count] 
FROM dimhour d LEFT JOIN cte2 ON 
d.hour = cte2.hourkey 
AND range IS NOT NULL 
WHERE d.hour <= 23 
GROUP BY d.hour, hourkey, range     
ORDER BY d.hour desc 

あなたが行がまったく表示したくない場合は、代わりにLEFT JOININNER JOINが必要になります。

SELECT d.hour, hourkey, range, COUNT(cte2.hourkey) AS [count] 
FROM dimhour d INNER JOIN cte2 ON 
d.hour = cte2.hourkey 
AND range IS NOT NULL 
WHERE d.hour <= 23 
GROUP BY d.hour, hourkey, range     
ORDER BY d.hour desc 
+0

'count(*)'は0に等しいので、意味があります。しかし、彼らはまだ表示されています。 – rbhat

+0

@rbhatupあなたのコメントごとに更新されました – Kateract

1

の式:

count(*) as [count] 

は数を返します結果セット内の行LEFT JOINは、一致しない場合でも少なくとも1つの行を保証しています。 JOIN(または主キー)のために使用される列のいずれかをカウントし、その後、試合をカウントする

count(cte2.hourkey) as [count] 

注:のみ、文字列、日付定数のための単一引用符を使用します。これらを列に使用すると、将来問題が発生する可能性があります。

あなたがGROUP BYを取る場合は、あなたが得る::私が考える方法で、別の視点から答えるように

0

が理解しやすいかもしれ

 
hour hourkey range 
18  NULL  NULL 
17  NULL  NULL 
16  NULL  NULL 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
15  15  99% 
14  14  99% 
... 

をあなたは今、グループ場合hourにより、 hourkeyrange18NULLNULLの行数私は1つの行を見つけます。それは一番上にあります。それはCOUNT(*)が返すものです。

これもこれに近づく方法です:必要なカウントは、この結果セットから簡単に得ることができるカウントですか?そうでない場合は、別のアプローチを探してください。あなたの場合、グループ化をcte2にしたいと思われます。だから代わりにそれを書いてください!

select d.hour, sub.hourkey, sub.range, sub."count" 
from dimhour d 
left join (
    select cte2.hourkey, cte2.range, count(*) as "count" 
    from cte2 
    where cte2.range is not null 
    group by cte2.hourkey, cte2.range 
) as sub 
on d.hour = sub.hourkey 
where d.hour <= 23 
order by d.hour desc 

一つの違いは、代わりに0の今、あなたがNULLを得るでしょうが、あなたはそれがあなたを悩ます場合ことを避けるためにISNULL(sub."count", 0)を使用することができることです。

関連する問題