• ベストアンサー

SQL・・

SQL構築で聞かせてください。 テーブル 名前    購入月   購入日 カローラ    4    18 プリウス    5     2 クラウン   12    22 なカンジです・・。 文章で表すと、例えば、 4月16日~5月15日までのデータを取りたいのです。 SELECT * FROM kounyuu WHERE 名前 = プリウス 購入月 = 4 AND 購入日 >= 16 SELECT * FROM kounyuu WHERE 名前 = プリウス 購入月 = 5 AND 購入日 <= 15 この2つの SELECT 文を1つにすることは可能ですか? (名前には、常に同じ値が入ります)

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

  • ベストアンサー
回答No.2

データベースの製品名とバージョンが分からないので、手元にある SQL Server 2005 で。 #1 さんの SQL だと 少なくとも SQL Server 2005 では、例えば 4/16 ~ 6/30 というように 3ヶ月にまたがる条件の場合に正しく検索できないように思います。 やや強引な感じですが、'testView' という名前の View を下記の定義で作成。 SELECT 名前, 購入月, 購入日, RIGHT('00' + CONVERT(nvarchar, 購入月), 2) + RIGHT('00' + CONVERT(nvarchar, 購入日), 2) AS 購入日付 FROM dbo.kounyuu 購入月と購入日をそれぞれ 頭が0から始まる 2桁の文字列にして連結した '購入日付' という計算列を作成しています。 カローラの行なら '0418' となり、プリウスの行なら '0502' となります。 この View に対して SELECT * FROM testView WHERE (購入日付 >= '0416') AND (購入日付 <= '0515') というような感じでどうでしょうか。 これなら開始日付と終了日付の 2つを指定するだけで済みます。

takuya_m
質問者

お礼

回答ありがとうございます。 回答でもらった意見をもう一度、今のシステムの考えのやり直しに役立てたいと思います・・。

その他の回答 (4)

回答No.5

RDBMS名とバージョンを書きましょう。 具体的なSQL例を提示しても、あなたの環境では使えないかも知れません。 年の跨りはないのですか? 月と日を別々に管理すると、以下のような面倒な条件になってしまいます。 m1月d1日~m2月m2日を検索する場合・・・ SELECT * FROM kounyuu WHERE 名前='プリウス' AND (月=m1 AND 日>=d1 AND 月=m2 AND 日<=d2 OR 月>m1 AND 月<m2) 年の跨りがあると、さらに年の条件も加わり、複雑になってしまいます。 RDBMSで、「(列名1,列名2)>=(値1,値2)」といった条件指定が可能なら、 以下の条件でも大丈夫ではないかと思います。 SELECT * FROM kounyuu WHERE 名前='プリウス' AND (月,日)>=(m1,d1) AND (月,日)<=(m2,d2) DATE型を使い、年月日を一つの列にすると簡単です。 表の定義は、 CREATE TABLE T1 (  ~中略~ 購入年月日 DATE,  ~中略~ ) 検索は、以下のようにできます。 SELECT * FROM kounyuu WHERE 名前='プリウス' AND (購入年月日>='2006-4-16' AND '2006-5-15') DATE型にすれば、年、月、日の部分だけを参照することもできます。

takuya_m
質問者

お礼

回答ありがとうございます。 >年の跨りはないのですか? すっかり忘れてました・・。 設計を1から見直し、DATE型にします。 貴重な意見、ありがとうございました。

回答No.4

DBが分りませんので、オラクルで言うと SELECT * FROM kounyuu WHERE 名前 = プリウス and (購入月*100+ 購入日) between 416 and 515 でいけると思います。 フィールドを計算した結果で比較しています。 ただし、インデックスを使用しなくなると思いますので、データ量に伴いレスポンス低下になると思います。 フィールド構成が変更可能であれば、#3さんのように 日付型にされたほうが簡単だと思います。

takuya_m
質問者

お礼

回答ありがとうございます。 全体的な意見をまとめ、設計をやり直します。 今回は、レスポンスの意見もいただき参考になりました。 ありがとうございました。

noname#182251
noname#182251
回答No.3

何か特別な理由がなければ、テーブルの設計を変えるべきだと考えます。 購入年月日:日付型 日付型から「年」「月」「日」を抽出することは簡単ですし、日数計算(例えば金利を計算する場合)なども楽にできます。後々のことも考え、如何でしょうか?

takuya_m
質問者

お礼

回答ありがとうございます。 1から設計の見直しをします。 勉強不足な自分に回答いただきありがとうございました。

  • toshi_2000
  • ベストアンサー率30% (306/1002)
回答No.1

次の通りです。 WHERE 名前 = プリウス AND( 購入月 = 4 AND 購入日 >= 16 OR 購入月 = 5 AND 購入日 <= 15)

takuya_m
質問者

お礼

回答ありがとうございます。 率直な回答ありがとうございました。

関連するQ&A

  • SQLについて

    こんにちは、honiyonです。  良い質問タイトルが思いつきませんでした...(^^;  2つのテーブルがあります。(仮定です)   ・オーナーの情報テーブル(owner)   ・オーナーの車の情報テーブル(car)  この2つのテーブルを利用して「男性の人で、黒い車に乗ってる人の車種名」を検索しようとしました。  これを1つのSQLで   SELECT car.name FROM owner,car WHERE (owner.no=car.ownerno) and (car.color='black') and (owner.sex='MAN');  とか、   SELECT car.name FROM (SELECT * FROM owner WHERE (owner.sex='MAN')) AS O2, (SELECT * FROM car WHERE (car.color='black')) AS C2 WHERE (owner.no=car.ownerno);  とかやってみましたが、涙が出るほど遅いです。  しかし   SELECT * INTO TABLE owner_tmp FROM (SELECT * FROM owner WHERE owner.sex='MAN'); SELECT * INTO TABLE car_tmp FROM (SELECT * FROM car WHERE car.color='black'); SELECT car_tmp.name FROM (owner_tmp.no=car_tmp.ownerno);  とすると超高速です。  なんとかテンポラリを作らず、出来れば1つのSQL文で高速に冒頭の処理を行いたいのですが、良い方法はないでしょうか。 是非お知恵を貸してください。  宜しくお願いします(.. #データベースはPostgreSQL 7.2.3です。

  • データの件数を集計するための SQL

    データの件数を集計するための SQL について教えてください。 例えば以下のようなテーブルがあります。 ▼テーブル 名前 |交通手段|日付 -----+--------+---- Aさん|バス |5/1 Aさん|バス |5/2 Aさん|バス |5/3 Bさん|バス |5/1 Bさん|電車 |5/2 ※「日付」については、本質問に直接の関係はありません。 このテーブルにクエリを発行して、以下の結果を取得したいと考えています。 ▼取得したい結果 名前 |交通手段|回数 -----+--------+---- Aさん|バス |3 Bさん|バス |1 Bさん|電車 |1 当方がイメージしている流れは以下の通りです。 SQL は苦手でして、これをひとつにまとめることができません。 1) GROUP BY で束ねる SELECT 名前, 交通手段 FROM テーブル GROUP BY 名前, 交通手段 2) 1)の結果の1件目をSELECTする SELECT COUNT(*) FROM テーブル WHERE 名前='Aさん' AND 交通手段='バス' 3) 1)の結果の2件目をSELECTする SELECT COUNT(*) FROM テーブル WHERE 名前='Bさん' AND 交通手段='バス' 4) 1)の結果の3件目をSELECTする SELECT COUNT(*) FROM テーブル WHERE 名前='Bさん' AND 交通手段='電車' なおレンタルサーバ上 (MySQL 5.0.77) で稼働させるため、 なるべく高速な SQL を希望いたします。

    • ベストアンサー
    • MySQL
  • DB2のSQL

    select * from xTABLE where EMP_ID = "P001" というSQLを実行すると SQL0206N "P001" is not valid in the context where it is used. SQLSTATE=42703 のエラーが出ます。 SQLSTATEで調べても「"P001"の列がテーブルにない」ということみたいですが 列名で捉えている時点でおかしい気がします select * from xTABLE where EMP_ID = null のSQLは正常にテーブルのSELECT結果が返ってきます。 どうすればよいでしょうか?

  • sqlのwhereで指定した条件の前後を取得したい

    テーブル=T) KEY DATA 001 あ 002 い 003 う 004 え 005 お SQL) SELECT DATA FROM T WHERE KEY = 003 ; 上記のSQLでは、「う」のデータしか取得できませんが、 「003」の前後1件、合計3件の「い」「う」「え」を取得する方法を教えて下さい。 ちなみに、 SELECT DATA FROM T WHERE KEY >= 003 AND ROWNUM <= 2 と SELECT * FROM ( SELECT DATA FROM T WHERE KEY < 003 ORDER BY KEY DESC ) WHERE ROWNUM < 1 のUNIONでは上手く行きませんでした。 よろしくお願いします。

  • 一つのSQLで実行できるでしょうか?

    sqliteで質問です。 今、以下のようなテーブル(table1)があったとします。 uid | date | comment 010 | 1211 | AAAAA 011 | 1211 | BBBBB 010 | 1220 | CCCCCC 011 | 1220 | DDDDDD このとき、1行目と4行目を取得や削除するようなSQLを一つで記述することは可能でしょうか? イメージてきには、 select * from table1 where {((uid = 010) and (date = 1211)), ((uid = 011) and (date = 1220))} みたいな感じにです。 つまり、where句の組み合わせを複数書いて一つのSQLで実行したいのです。 恐れ入りますが、よろしくお願いします。

  • SQL文

    名前、性別、年齢の載っているA表から19歳以下の女性、または26歳以上の女性の名前を抽出するSQL文はSELECT 名前 FROM 表A WHERE 性別=’女’AND 年齢<20 OR 性別=’女’AND 年齢>25 が正解ですが、性別=’女’を1回にして SELECT 名前 FROM 表A WHERE 性別=’女’AND 年齢<20 OR  年齢>25 ではだめでしょうか。教えてください。

  • SQL文について困っています

    ID(NUMBER型)と NUM(NUMBER型)と nenngetu (date型)を持ったテーブルAAAから、 ID=1000 のなかで日時が一番古い処理NOをselectするSQL文を書きましたが上手く実行されません。 select NUM from AAA where nenngetu = (select min(nenngetu) from AAA) and ID=1000; ID=1000の条件をはぶき、 select NUM from AAA where nenngetu = (select min(nenngetu) from AAA); でしたら、実行できました。 oracleで実行しようとしています。 どなたか、書き方を教えてください。

  • SQL文について

    SQL文について 現在一度に検索ができずに困っているため質問します。 データベースに男性テーブルと女性テーブルがあります。 男性テーブル ・番号 ・名前 女性テーブル ・番号 ・名前 このテーブルより自分の父、母、母の父を表示させたいのですが SELECT 男性テーブル.名前, 女性テーブル.名前, (※母の父を表示させたい) FROM 男性テーブル, 女性テーブル WHERE 男性テーブル.番号=父の番号 AND 女性テーブル.番号=母の番号 このあと条件に (AND 男性テーブル.番号=母の父の番号) をつけることはできないためSQL文の書き方で困っています。 抽出データは複数なので※の部分にサブクエリを書くことができません。 何かよいSQLの書き方はありますでしょうか?

  • oracleからSQL Serverへの移行

    oracleからSQL Serverへ移行することになったのですが、副問い合わせで定義したテーブル同士を外部結合するSQL構文が、うまく実現できず、ご教授して頂きたくよろしくお願いします。 下記、oracle 構文をSQL Server構文へ書き換えたい。 select * from (select cal1,cal2,cal3 from tbl1,tbl2 where cal1 >100) aaa, (select cal1,cal2,cal3 from tbl1,tbl2 where cal1 <=100) bbb, tbl3 where aaa.cal1 = bbb.cal1(+) and aaa.cal2 = bbb.cal2(+) and aaa.cal3 = bbb.cal3(+) and aaa.cal1 = tbl3.cal1 よろしくお願いします。

  • SQL文でのデータの取得が上手くいきません

    初めて質問させていただきます。 こちらのカテゴリで良いのか分からなかったのですが、よろしくお願いいたします。 SQL文を作成しているのですが、上手くいかず困っている状況です。 要件としてはテーブルAにユーザーの情報が格納されているのですが、 キーの一つとして世代(SEDAI_NO)(日付)を持っております。 今回取り出したいデータは該当ユーザーの処理日以前の最新のデータを 取得したいと思い以下のSQL文を作成しましたが、上手く行かず、最新世代を含むそれ以前の世代のデータを取得してきています。 どこがおかしいのでしょうか? よろしくお願いいたします。 【作成したSQL】 select * from テーブルA テーブルA’ where (USER_ID=該当のユーザーID) and (SEDAI_NO = (select max(SEDAI_NO) from テーブルA where SEDAI_NO = テーブルA’.SEDAI_NO AND 処理日 >= テーブルA'.SEDAI_NO)