- ベストアンサー
HAVING句でのBETWEEN演算子の使い方とグルーピングについて
- HAVING句でのBETWEEN演算子を利用することで、指定した範囲の条件を満たすデータを抽出することができます。
- MS SQL SERVERのフロントエンドであるMS ACCESSでパススルークエリを作成している際に、指定した時間範囲のデータを抽出するために、BETWEEN演算子を使用しています。
- ただし、グルーピングしたデータに対してHAVING句を使用する際には、正しいグループ化キーを指定する必要があります。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
例えば、次のようなJOBのデータがあるとします。 I ID Time 1 AAA 2005/06/01 0:00:10 2 BBB 2006/02/01 0:00:10 3 CCC 2006/03/01 0:00:10 4 AAA 2006/02/01 0:00:10 5 BBB 2006/02/02 0:00:10 6 CCC 2006/03/02 0:00:10 SELECT DISTINCT ID FROM JOB GROUP BY ID,time HAVING TIME between '2006/01/01 00:00:00' and '2006/02/02 23:59:59' ORDER BY ID というSQL文の実行結果は... |ID | ---|---- 1|AAA| 2|BBB| <SQL Server 2000> 質問者は、かような結果を期待しているのでしょうか?
その他の回答 (2)
s_husky です。 質問を読み間違っていました。 |ID |Time | ---|----------------------- 1|AAA|2006/02/01 0:00:10| 2|BBB|2006/02/01 0:00:10| という結果を欲しているならば... Select distinct ID , max(time) as time From job Where Time > '2006/01/01 23:59:59' and Time < '2006/02/01 23:59:59' group by id ※指定された範囲に合致するIDを一意に抜き出し、その間のtimeの最大値を取得する。 ※これで、事実上、同一の結果が求まると思います。
- chukenkenkou
- ベストアンサー率43% (833/1926)
どういうエラーになったのでしょうか? GROUP BY指定時、SELECTで選択できるのは、GROUP BYで指定した列か集合関数だけではないでしょうか? 【正】 SELECT C1,COUNT(*) FROM T1 GROUP BY C1 【誤】 SELECT C1,C2,C3 FROM T1 GROUP BY C1 MySQLではSQLの拡張仕様として、上記の書き方も許していますが、他の殆どのRDBMSではエラーになると思います。 >IDをグルーピングしたいと思い 今の指定では、IDでグループ化した場合、TIMEと対応付けられなくなりますよね? >SELECT ID, TIME >FROM JOB >GROUP BY CODE >HAVING TIME between '2006/01/01 00:00:00' >and '2006/01/31 23:59:59' >ORDER BY ID 説明にない列「CODE」でグループ化していますが、「ID」の間違いですか? 「GROUP BY CODE」は、「GROUP BY ID」の間違いと仮定して、SQL例を示します。 【例1】グループ化するIDのみ取り出す SELECT ID FROM JOB GROUP BY ID HAVING TIME between '2006/01/01 00:00:00' and '2006/01/31 23:59:59' ORDER BY ID 【例2】TIMEはIDのグループ毎の最大値を取り出す SELECT ID, MAX(TIME) FROM JOB GROUP BY ID HAVING TIME between '2006/01/01 00:00:00' and '2006/01/31 23:59:59' ORDER BY ID
お礼
SELECTの理解不足だったようです。WHERE句で簡単にできることに気がつきました。 SELECT ID FROM JOB WHERE TIME between '2006/01/01 00:00:00' and '2006/02/02 23:59:59' GROUP BY ID ORDER BY ID ACCESSだとTIMEを一旦フィールドに入れるのでSQLでも一旦SELECTで選択する必要があると勘違いしていました。 教えていただいたSQL文で気づきました。 ありがとうございました。
補足
>>説明にない列「CODE」でグループ化していますが、「ID」の間違いですか? すみません。おっしゃるとおり間違いでした。 エラーですが、「TIME は集合関数やGROUP BY句に含まれないのでHAVINGでは有効とならない」と書いてあります。(#8121) ACCESSの感覚でSQL書いているからだめなんでしょうね。勉強します。 残念ながらいただきましたSQL文でも同様のエラーがでてしまいました。でもアドバイスありがとうございました。
お礼
ありがとうございます。まさにこれです。 原因1 HAVING句のTIMEはGROUP BYのところにもないといけないということですね。 GROUP BY ID →GROUP BY ID,TIMEに書き換えることでエラーが出なくなりました。 原因2 GROUP BY ID,TIMEと書き換えただけの場合、グルーピングはIDとTIMEをひとつの組み合わせとして行われるので、 IDがユニークとしては表示されなくなるので、DISTINCT IDを実施して重複レコードを削除するんですね。 変更後のSQL文 SELECT DISTINCT ID FROM JOB GROUP BY ID,TIME HAVING TIME between '2006/01/01 00:00:00' and '2006/02/02 23:59:59' ORDER BY ID 結果 ID AAA BBB なるほどですね。 ありがとうございました。