- ベストアンサー
同一テーブル内のデータを比較条件で集計し表示するには?
商品 価格 -------------------- 白米 15000 玄米 14000 なす 5000 きゅうり 3000 上記のようなテーブルから、 価格が10000までの商品点数、また10000~20000の 商品点数を一回のSQL文で取得できるようなクエリー を作りたいのですが、アドバイス頂けましたら幸いですm(__)m
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
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で作り込んで、それごとの件数を表示する考え方です。
その他の回答 (6)
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
テストしていないので、気づきませんでしたが.. SQLserverだと、インラインビューにも別名を付与しないと いけないかも。 select * from (select ~) as 別名 この別名の箇所は、お好きな名称を付けていただけばOKです。
お礼
ありがとうございます。 その通りでした! 非常に丁寧にアドバイスいただきまして 本当にありがとうございました。
- fu_u_ka_i
- ベストアンサー率51% (15/29)
>#3 & #4 ・select (select~),(select ~) フィールリス上のサブクエリは、テーブルスキャンが 個々に行われる可能性が高く、実行効率的に不利です。 この機能を使わないと実現できない場面以外では、 避けた方が良い考え方です。 ・select ~ union select ~ 当然ながら、これもテーブルスキャンが複数回行われる 可能があり、実行効率的に不利です。 個々に問い合わせる理由が無ければ、unionを使うのは つまらないと思いますが.. なお、今回のケースで、価格に索引が付いていれば、 探査範囲が局所化され、重複して読み出す訳ではな いので、結果として、許容可能なレベルの"遅さ"で あるかも知れません。 逆に、価格に索引が無く、テーブルフルスキャンが 必要なケースで、大量のデータを扱う場合、極端に 遅いものとなります。
補足
チューニング的な説明を詳しく教えて頂きありがとうございます。非常に勉強になります。 クエリーを連結する方法以外で、 項目 件数 ------------------------------- 10000以下 2 10000~20000 2 20000以上 0 のような結果を返すクエリを作成したいのですが、勉強不足で苦労しております。よろしければ、もう一度アドバイス頂けましたら幸いです。
- Azzuri
- ベストアンサー率68% (34/50)
#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
補足
ありがとうございます。 クエリーを連結する方法以外でできれば探したいのですが、よろしければ、またアドバイスください。
- Azzuri
- ベストアンサー率68% (34/50)
このような方法もあります。 一行: 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
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
一行に集約して結果を得るなら 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 集約キー のように求めても良いと思います。
補足
早々とアドバイスありがとうございます。 補足ですが、取得したい結果は、 項目 件数 ------------------------------- 10000以下 2 10000~20000 2 20000以上 0 みたいな感じです。複数行で返す方法を試させて頂きましたが、「集約キー」の部分が理解できず動作させることができませんでした。お時間ございましたらもう一度アドバイス頂けましたら幸いです。
- turtlemach
- ベストアンサー率54% (29/53)
SELECT COUNT(*) AS 商品点数 FROM 商品テーブル WHERE 価格 > 10000 AND 価格 < 20000 といった感じでいかかでしょう。 きちんと確認できる環境にないので、自信「なし」です。
お礼
たびたびアドバイスありがとうございました。 おかげさまで意図した結果を得る事ができ大変感謝しております。 最終的にクエリは以下のようになりました。 「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 項目