こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

同一テーブル内のデータを比較条件で集計し表示するには?

商品     価格
--------------------
白米     15000
玄米     14000
なす      5000
きゅうり    3000

上記のようなテーブルから、
価格が10000までの商品点数、また10000~20000の
商品点数を一回のSQL文で取得できるようなクエリー
を作りたいのですが、アドバイス頂けましたら幸いですm(__)m

投稿日時 - 2005-03-20 00:12:53

QNo.1279629

困ってます

質問者が選んだベストアンサー

SQLが間違っていたみたいですね。(caseの終了"END"が抜けてました)

select 項目,count(*) as 件数
from
(select
case when 価格 <= 10000 then '10000以下' when 価格 <= 20000 then '10001~20000'
else '20000以上' END as 項目 from テーブル)
group by 項目

集約すべき単位をCASEで作り込んで、それごとの件数を表示する考え方です。

投稿日時 - 2005-03-21 03:10:57

お礼

たびたびアドバイスありがとうございました。
おかげさまで意図した結果を得る事ができ大変感謝しております。
最終的にクエリは以下のようになりました。
「DERIVEDTBL」の意味がまだ理解できてないのですが、
付けないと構文エラーになります。SQLServer2000の仕様でしょうか?
SELECT 項目, COUNT(*) AS 件数
FROM (SELECT CASE WHEN 価格 <= 10000 THEN '10000以下' WHEN 価格 <= 20000 THEN '10001~20000' ELSE '20000以上' END AS 項目 FROM veg)
DERIVEDTBL
GROUP BY 項目

投稿日時 - 2005-03-21 15:37:25

このQ&Aは役に立ちましたか?

13人が「このQ&Aが役に立った」と投票しています

回答(7)

テストしていないので、気づきませんでしたが..

SQLserverだと、インラインビューにも別名を付与しないと
いけないかも。

select * from (select ~) as 別名

この別名の箇所は、お好きな名称を付けていただけばOKです。

投稿日時 - 2005-03-21 23:18:10

お礼

ありがとうございます。
その通りでした!
非常に丁寧にアドバイスいただきまして
本当にありがとうございました。

投稿日時 - 2005-03-23 12:47:56

ANo.5

>#3 & #4

・select (select~),(select ~)

フィールリス上のサブクエリは、テーブルスキャンが
個々に行われる可能性が高く、実行効率的に不利です。
この機能を使わないと実現できない場面以外では、
避けた方が良い考え方です。

・select ~ union select ~

当然ながら、これもテーブルスキャンが複数回行われる
可能があり、実行効率的に不利です。
個々に問い合わせる理由が無ければ、unionを使うのは
つまらないと思いますが..

なお、今回のケースで、価格に索引が付いていれば、
探査範囲が局所化され、重複して読み出す訳ではな
いので、結果として、許容可能なレベルの"遅さ"で
あるかも知れません。

逆に、価格に索引が無く、テーブルフルスキャンが
必要なケースで、大量のデータを扱う場合、極端に
遅いものとなります。

投稿日時 - 2005-03-20 21:59:34

補足

チューニング的な説明を詳しく教えて頂きありがとうございます。非常に勉強になります。
クエリーを連結する方法以外で、

項目        件数
-------------------------------
10000以下       2
10000~20000     2 
20000以上       0

のような結果を返すクエリを作成したいのですが、勉強不足で苦労しております。よろしければ、もう一度アドバイス頂けましたら幸いです。

投稿日時 - 2005-03-20 22:19:01

ANo.4

#3です。
少し記述ミスがありました。以下が訂正内容です。
一行:
select (select COUNT(*) FROM 商品 WHERE 価格 <= 10000) AS CNT10000,
(select COUNT(*) FROM 商品 WHERE 価格 BETWEEN 10001 and 20000) AS CNT20000

複数行:
select '1万以下' AS NAME,COUNT(*) AS CNT FROM 商品 WHERE 価格 <= 10000
union
select '1万~2万' AS NAME,COUNT(*) AS CNT FROM 商品 WHERE 価格 BETWEEN 10001 and 20000

投稿日時 - 2005-03-20 17:51:47

補足

ありがとうございます。
クエリーを連結する方法以外でできれば探したいのですが、よろしければ、またアドバイスください。

投稿日時 - 2005-03-20 22:16:58

ANo.3

このような方法もあります。
一行:
select (select COUNT(*) 商品 TEST WHERE 価格 <= 10000) AS CNT10000,
(select COUNT(*) FROM 商品 WHERE 価格 BETWEEN 10001 and 20000) AS CNT20000

複数行:
select '1万以下' AS NAME,COUNT(*) AS CNT FROM TEST WHERE B <= 10000
union
select '1万~2万' AS NAME,COUNT(*) AS CNT FROM TEST WHERE B BETWEEN 10001 and 20000

投稿日時 - 2005-03-20 17:46:01

一行に集約して結果を得るなら

select
sum(case when 価格 <= 10000 then 1 else 0 end) as 1万以下の件数,
sum(case when 価格 > 10001 and 価格 <= 20000 then 1 else 0 end) as 2万以下の件数
from テーブル

のように求められますし、複数行で返したいなら

select 集約キー,count(*) as 件数
from
(select
case when 価格 <= 10000 then '1万以下' when 価格 <= 20000 then '2万以下'
else 'その他' as 集約キー from テーブル)
group by 集約キー

のように求めても良いと思います。

投稿日時 - 2005-03-20 03:20:14

補足

早々とアドバイスありがとうございます。
補足ですが、取得したい結果は、

項目        件数
-------------------------------
10000以下       2
10000~20000     2 
20000以上       0

みたいな感じです。複数行で返す方法を試させて頂きましたが、「集約キー」の部分が理解できず動作させることができませんでした。お時間ございましたらもう一度アドバイス頂けましたら幸いです。

投稿日時 - 2005-03-20 21:58:03

ANo.1

SELECT COUNT(*) AS 商品点数
FROM 商品テーブル
WHERE 価格 > 10000 AND 価格 < 20000

といった感じでいかかでしょう。

きちんと確認できる環境にないので、自信「なし」です。

投稿日時 - 2005-03-20 00:38:01

あなたにオススメの質問