プロが教える店舗&オフィスのセキュリティ対策術

MySQLで、複数のカラム値の計算結果をASで新しいカラム名で出力し、新しいカラム名で抽出を行った時にレコード数をカウントする方法を知りたいです。
WHERE句ではエラーになるのでHAVING句を使うということまではわかったのですが、結果の総レコード数を出力することができません。


テーブル名:s

id | a | b
1 | 100 | 200
2 | 200 | 80
3 | 300 | 20
4 | 400 | 90
5 | 500 | 40

下記のような手順を踏んでみました。

まず、WHERE句で全件を出力
SELECT count(id) FROM s WHERE 1
[結果]
count(id)
5

ASを使わない aカラムで抽出
SELECT count(id) FROM s WHERE 1 AND a BETWEEN 200 AND 400
[結果]
count(id)
3


AS を使って (a/b)*100 を計算したカラム c を作成
SELECT id,a,b,(a/b)*100 as c FROM s WHERE 1 AND a BETWEEN 200 AND 400
idが2,3,4の3件分のデータが表示される

id | a | b | c

2 | 200 | 80 | 250.0000
3 | 300 | 20 |1500.0000
4 | 400 | 90 | 444.4444


cカラム(計算した結果)でBETWEENを実行
SELECT id,a,b,(a/b)*100 as c FROM s WHERE 1 AND c BETWEEN 200 AND 500
エラーになる
#1054 - Unknown column 'c' in 'where clause'

ASを使った時に Where句では c を指定できないのでHAVING句を使うということを知り、WHERE句をHAVING句に書き換える。

SELECT id,a,b,(a/b)*100 as c FROM s HAVING 1 AND c BETWEEN 200 AND 500
id | a | b
1 | 100 | 200 |333.3333
2 | 200 | 80 |250.0000
4 | 400 | 90 |444.4444


この結果のレコード数をcountで取得したいです。
SELECT count(*),id,a,b,(a/b)*100 as c FROM s HAVING 1 AND c BETWEEN 200 AND 500
SELECT count(id),id,a,b,(a/b)*100 as c FROM s HAVING 1 AND c BETWEEN 200 AND 500
これだと結果が5件になってしまいます。

idでグループ化すれば良いと思い
SELECT count(id),id,a,b,(a/b)*100 as c FROM s GROUP BY id HAVING 1 AND c BETWEEN 200 AND 500
を実行

count(id) | id | a | b | c
1 | 1 | 100 | 30 | 333.333333300
1 | 2 | 200 | 80 | 250.000000000
1 | 4 | 300 | 90 | 444.444444400

HAVINGとGROUPを使っているので、このように3行の結果が出るのは当然だと思うのですが、この時の結果を「SELECT count(*) FROM WHERE 1」の時と同じように
count(id)
3
という合計値だけ出力するようにしたいです。

ご回答よろしくお願い致します。


~~~~~~~~~~~~~~~~~~
テストデータ
~~~~~~~~~~~~~~~~~~

CREATE TABLE `s` (
`id` int(11) NOT NULL,
`a` int(3) NOT NULL,
`b` int(3) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

INSERT INTO `s` (`id`, `a`, `b`) VALUES
(1, 100, 30),
(2, 200, 80),
(3, 300, 20),
(4, 400, 90),
(5, 500, 40);

ALTER TABLE `s`
ADD PRIMARY KEY (`id`);

ALTER TABLE `s`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=6;

A 回答 (1件)

havingの使い方がおかしい



SELECT count(id) FROM s where 1 AND (a/b)*100 BETWEEN 200 AND 500
    • good
    • 0
この回答へのお礼

yambejpさま

ご回答ありがとうございました。
教えていただいたSQL文で総数が取得できました。

計算後のカラムでソートを使いたかったので教えていただいたSQL文を
SELECT id,(a/b)*100 as c FROM s where 1 AND (a/b)*100 BETWEEN 200 AND 500 ORDER BY c ASC
というようにしましたらデータの抽出とソートもうまくいきました。

where句の中で c が使えないので、 (a/b)*100 という計算式を直接指定すればよかったのですね。having句の中では asで指定したカラム名を使えるという情報があったので、Whereと同じような使い方ができるのかもしれないと思ったのですが、ダメなんですね。

お礼日時:2016/05/22 14:11

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!