外出自粛中でも楽しく過ごす!QAまとめ>>

学校でSQLを使って、データベースを作るという期末課題がでました。

当方バイクの知識が少々あるため、バイクとバイク販売店というデータベースを作ってみることにしました。

バイクのデータ100個分とお店のデータは10個ほどなのですが、課題の条件の中にVIEWを作成すること、とあるのですが、VIEWとは何者なのでしょうか?
授業のページを見ても、難しい事しか載っていなくて困っています。

またテーブルの入力と、データの入力はなんとか覚えたのですが、VIEWの作り方は全く意味がわかりません。なので・・・

VIEWの意味と役割を教えてください。
初心者なので出来るだけわかりやすく教えていただけたら幸いです。
またVIEWの作成方法(create viewだとかなんとか・・・)を教えてください。
ちなみにテーブルデータとかはこんな感じに作っております。なのでこんな感じでVIEWの作成方法をご教授いただけたらありがたい次第です。
create table bike(
  maker text,
name text,
size int,
nennshiki date,
kaizou text,
shaken text,
nedann float,
shop text
)

よろしくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

#1回答者です。



バイクは詳しくないので、自動車の例で説明します。

一つの表で、メーカー名や車種名などを管理すると、冗長な情報を管理することになってしまいます。

=====表定義例=====
create table メーカー
(メーカーid smallint primary key,
メーカー名 varchar(16));

create table 車種
(メーカーid smallint,
車種id smallint,
車種名 varchar(30),
primary key(メーカーid,車種id));

create table 型名情報
(メーカーid smallint,
車種id smallint,
型名 varchar(30) primary key,
年式 smallint,
排気量 smallint,
定価 int);
create index 型名情報idx on 型名情報(メーカーid,車種id);
=====ここまで=====

このように分けることで、メーカー名を車の情報分、持たなくてすみます。
仮にメーカー名が変更になった場合は、「メーカー」表のみを更新すればよくなります。

「マーチ」といった車種で、いろいろな年式があるでしょうから、車種名と年式といった情報も、表を分けます。

このようにして置くと、情報変更時の更新箇所が限られるし、メーカーの検索、車種名の検索といったことが容易に行えます。

=====データ例=====
insert into メーカー values(1,'TOYOTA');
insert into メーカー values(2,'NISSAN');
insert into メーカー values(3,'HONDA');

insert into 車種 values(1,1,'カローラ XXXX');
insert into 車種 values(1,2,'クラウン XXXX');
insert into 車種 values(2,1,'スカイライン XXXX');
insert into 車種 values(2,2,'マーチ');
insert into 車種 values(3,1,'アコード');

insert into 型名情報 values(1,1,'ABC-DEF-1234',2003,1600,150);
insert into 型名情報 values(1,1,'ABC-DEF-1240',2005,1600,160);
insert into 型名情報 values(1,2,'ABC-XYZ-1111',2005,2000,250);
insert into 型名情報 values(2,1,'EFGH-IJK-LMN-12',2002,2000,200);
insert into 型名情報 values(2,2,'HIJK-LMN-OPQ-20',2005,1600,120);
insert into 型名情報 values(3,1,'XY-ZABC-DE-12345',2003,2000,200);
=====ここまで=====

いよいよ検索です。
三つに分けた表から、メーカー名や車種名、年式といった情報を検索します。

=====検索SQL例=====
select x.メーカー名,y.車種名,年式,排気量,定価
from (メーカー as x
left join 車種 as y
on x.メーカーid=y.メーカーid)
left join 型名情報 as z
on y.メーカーid=z.メーカーid and y.車種id=z.車種id;
=====ここまで=====

少し複雑になってしまいました。
これをビューにして登録しておき、検索SQLは簡単に記述できるようにしてしまいます。

=====ビュー定義例1=====
create view 車検索
as
select x.メーカー名,y.車種名,年式,排気量,定価
from (メーカー as x
left join 車種 as y
on x.メーカーid=y.メーカーid)
left join 型名情報 as z
on y.メーカーid=z.メーカーid and y.車種id=z.車種id;
=====ここまで=====

このビューを利用して検索する場合、検索SQLは以下のように簡単に記述できます。

=====ビューを使った検索1=====
select * from 車検索;
=====ここまで=====

ビューで、特定のデータのみ見せる(他のデータは見せない)ことが可能です。
例えば上述のビューを「TOYOTA」の車種のみを見せるビューに変えてみます。

=====ビュー定義例2=====
drop view 車検索;
create view 車検索
as
select x.メーカー名,y.車種名,年式,排気量,定価
from (メーカー as x
left join 車種 as y
on x.メーカーid=y.メーカーid)
left join 型名情報 as z
on y.メーカーid=z.メーカーid and y.車種id=z.車種id
where x.メーカー名='TOYOTA';
=====ここまで=====

以下の検索(「ビューを使った検索1」と同じ)を行うと、今度は「TOYOTA」の車種しか見えなくなります。

=====ビューを使った検索2=====
select * from 車検索;
=====ここまで=====

このようにビューを使うと、特定のデータだけ見せたり、SQLを簡単にできるといったメリットがあります。
    • good
    • 5

#1、#3回答者です。



ビューの役割や使い方を説明しましたが、ビューとは何かを説明していませんでしたね。

ビューというのは、実体(DB中のデータ)を持たない仮想の表です。
ビューを利用時に、ビューで参照している表から、実際のデータが持ってこられます。

使う目的や使い方は、既に回答の通りです。
    • good
    • 2

viewは元ある表から生成された表のことです。

以下のような表があるとしましょう。名前は商品一覧です。
商品名  |倉庫|単価
Tシャツ |A1|100
ジーンズ |A1|200
スカート |B1|150
キャップ |B2|50
これが元の表のときに、例えば倉庫A1にあるものだけを一覧にして見たい、と。そのときこのようにviewを作ります↓
create view 倉庫A1 as select * from 商品一覧 where 倉庫='A1';
すると、倉庫A1というviewが生成され、テーブル一覧\dでもselect * from 倉庫a1;でもビューの内容は確認できます。
viewは元の表のように削除はできないため、viewを消すときはviewごとdrop view 倉庫a1;で消します。
    • good
    • 1
この回答へのお礼

回答ありがとうございます。詳しい説明をいただき、なんとか少しづつ理解できそうです。
感謝いたします。

お礼日時:2006/07/15 01:49

各列には、どのような値を入れるのですか?



textなんて使用するのはやめて、varchar(n)にしましょう。
→「文章をそのまま格納する」といった要件以外では、文字数の上限がある程度分かるはずです。また、textは近い将来、削除される予定です。

floatなんて使用するのはやめて、intやdecを使用しましょう。
→floatは概数であり、大きな数値を表せる半面、小数点以下の値は誤差が出ます。

ビューの使用目的は、幾つかあります。

(1)特定の列のみ見せる
(2)特定の行のみ見せる
(3)複雑なSQLをビューで吸収し、操作時のSQLは簡単に書けるようにする

などです。
    • good
    • 4
この回答へのお礼

わざわざ丁寧な回答ありがとうございます。
とても参考になりました。感謝いたします。
それにしても、少し覚えるまでに、時間がかかりそうですね。頑張って覚えたいと思います。

お礼日時:2006/07/15 01:48

このQ&Aに関連する人気のQ&A

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

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

Q3つの表の外部結合

表A、B、Cの3つがあり、Aのすべての行を出力したいと考えています。
外部結合を用いるのだとは思うのですが、3つの表に対して行う場合の
書き方がわからず困っています。
ご教授いただけないでしょうか?
select * from a,b,c
where a.商品ID =b.商品ID (+) and b.商品ID (+) =c.商品ID (+)
としてみましたが、うまくいきませんでした。

Aベストアンサー

ansi構文の趣旨からいえば、結合条件と絞り込み条件は分けて書くので・・

select *
from a
left join b on (a.商品ID =b.商品ID)
left join c on (b.商品ID =c.商品ID)
where a.年月 = 任意の値

と書くのが一般的でしょうね。

QInner join と Left joinの明確な違いは?

Inner join と Left joinの違いがよくわかりません。
教えてください。

Aベストアンサー

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
4               NULL
5               NULL
6               NULL
の6レコードが出力されますが、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 INNER JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
の3レコードしか出力されません。

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3           ...続きを読む

QSQLで特定の項目の重複のみを排除した全項目を取得する方法

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のような構造になっている場合に「項目名1」について重複している項目を排除し、結果として


項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 B    え    イ    江

上のようなデータを取得したいのです。
この時に、Aの重複を排除して取得するレコードは1~3行目のどれでもよいです。
また、データを取得する際には必ずそのレコードの「全項目」を取得したいのでDistinctはうまく使えませんでした。

どなたか詳しい方、方法を教えてくださると幸いです。回答お待ちしております。

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のよ...続きを読む

Aベストアンサー

比較可能で一意性のある値をもてる項目6をテーブルに追加して、

select T.* from T, (select Item1,min(Item6) as Item6 from T group by item1) W where T.item6=W.item6;

――ってやるのが、一番手っ取り早いと思います。
他のところに影響がでないのであればですが。
oracleならrowidを使うとか、レコードの更新時刻を突っ込むとか。

Qデータベース内のテーブル名の取得

お世話になります。
初心者的な質問でしたらすいません。
SQL文にてデータベース内のテーブル名を
調べることができると聞いたことがあるのですが、
可能でしょうか。

もし、可能であれば、SQLの記述を教えてください。
お願いします。

Aベストアンサー

select * from tab;

私の場合、テーブル名だけ手っ取り早く知りたいとき、↑を打ちます。その他の情報も知りたいときは#2さんの仰るとおり、user_tablesで取得します。

Q2つのテーブルから条件に一致しないデータ抽出

2つのテーブルから条件に一致しない行のみ抜き出しCSV
か他のテーブルに抜き出す処理を作ろうと思っています。

そこで質問なのですが、以下の2つのテーブルから
条件に一致しないコードのみ抜き出すSQL文などありますか?

-----------------------------------------
マスターテーブル
コード、ネーム1、ネーム2、店コード
1、あ、い、6
2、う、え、8
3、お、か、4
4、き、く、2


店コードテーブル
店コード、店区分
1、スーパー
2、コンビニ
3、デパート
4、ホームセンター
------------------------------------------

条件は、マスターテーブルの店コードが店コードテーブルに存在
しないデータのみ抽出です。

抽出結果は、以下の様にしたいです。
1、あ、い、6
2、う、え、8

このような考え大丈夫でしょうか?
SELECT *
FROM マスターテーブル AS M INNER JOIN 店コードテーブル AS S
ON M.店コード = S.店コード

わかりずらい質問ですがよろしくお願いします。

2つのテーブルから条件に一致しない行のみ抜き出しCSV
か他のテーブルに抜き出す処理を作ろうと思っています。

そこで質問なのですが、以下の2つのテーブルから
条件に一致しないコードのみ抜き出すSQL文などありますか?

-----------------------------------------
マスターテーブル
コード、ネーム1、ネーム2、店コード
1、あ、い、6
2、う、え、8
3、お、か、4
4、き、く、2


店コードテーブル
店コード、店区分
1、スーパー
2、コンビニ
3、デパート
4、ホームセンタ...続きを読む

Aベストアンサー

このような考え大丈夫でしょうか?
SELECT *
FROM マスターテーブル AS M INNER JOIN 店コードテーブル AS S
ON M.店コード = S.店コード

店コードが一致するレコードを抽出しているのですね。
はい、大丈夫です。
もっとも単純に、分かりやすい式を書くのであれば

この条件否定なので
left outer join で結合して、結合できなかったデータ、
つまり、店がNullのデータを取れば抽出できます。

SELECT *
FROM マスターテーブル AS M left outer join 店コードテーブル AS S
ON M.店コード = S.店コード
where S.店コード is null

または、
SELECT *
FROM マスターテーブル as M
where M.店コード not in ( select 店コード from 店コードテーブル)

等でいけるでしょう。

ただ、参考URLにもありますように、
is null とか not in は遅いです。(Indexで見れなくなるので)
大量データを扱うような場合や、速度が求められるような場合は
別途クエリを検討しましょう。

参考URL:http://www.geocities.jp/mickindex/database/db_optimize.html

このような考え大丈夫でしょうか?
SELECT *
FROM マスターテーブル AS M INNER JOIN 店コードテーブル AS S
ON M.店コード = S.店コード

店コードが一致するレコードを抽出しているのですね。
はい、大丈夫です。
もっとも単純に、分かりやすい式を書くのであれば

この条件否定なので
left outer join で結合して、結合できなかったデータ、
つまり、店がNullのデータを取れば抽出できます。

SELECT *
FROM マスターテーブル AS M left outer join 店コードテーブル AS S
ON M.店コード = S....続きを読む

QSELECTで1件のみ取得するには?

こんにちわ。
いまORACLE9iを使用している者です。

ACCESSでは
SELECT TOP 1 項目名 FROM テーブル名
ORDER BY 項目名;
で並べ替えたデータ群のうち,先頭の1件だけを
取ることができますが,
ORACLEでそのような機能(SQL)はあるでしょうか?
教えてください。
よろしくお願いします。

Aベストアンサー

order by と rownum を併用する場合は注意が必要です。

[tbl01]
cola | colb
------------
1000 | aaaa
1001 | bbbb

というデータがある場合、
select cola from tbl01 where rownum < 1 order by cola desc;
とすると、「1001」ではなく、「1000」が返されます。
これは、order by の前に rownum < 1 が適用されてしまうからです。

解決するには、
select aaa from (select cola aaa from tbl01 order by cola desc) where rownum = 1;
とすれば良いです。

QLEFT JOINが2つあるSQL文でANDの意味

■下記SQL文の意味を教えてください

SELECT a.*, b.being_name
FROM alive a
 LEFT JOIN being b ON a.hoge_id = b.id
 LEFT JOIN call c ON c.call_id = a.hoge_id
  AND f.hoge_id = 12
 WHERE f.hoge_id = 12 OR b.id = 12

※12の部分は動的に切り替わります

・LEFT JOINが2つあるので、3つのテーブルを結合しているのでしょうか?
・左テーブルは「alive a」で、この右側に2つのテーブルが結合している、という認識でよいでしょうか?

>SELECT フィールド名 FROM テーブル名 WHERE 条件式1 AND 条件式2
>「AND」は2つの条件式の論理積
・上記内容をネットで見かけたのですが、「AND」は、「WHERE」の前に来てもいいのでしょうか? それともこのSQLの「AND」は違う使い方をしているのでしょうか? 何か、LEFT JOINに関係しているのでしょうか?

■下記SQL文の意味を教えてください

SELECT a.*, b.being_name
FROM alive a
 LEFT JOIN being b ON a.hoge_id = b.id
 LEFT JOIN call c ON c.call_id = a.hoge_id
  AND f.hoge_id = 12
 WHERE f.hoge_id = 12 OR b.id = 12

※12の部分は動的に切り替わります

・LEFT JOINが2つあるので、3つのテーブルを結合しているのでしょうか?
・左テーブルは「alive a」で、この右側に2つのテーブルが結合している、という認識でよいでしょうか?

>SELECT フィールド名 FROM テーブル名 WHERE 条件式1 AND 条件式...続きを読む

Aベストアンサー

>・LEFT JOINが2つあるので、3つのテーブルを結合しているのでしょうか?
はいそうです。

>左テーブルは「alive a」で、この右側に2つのテーブルが結合している、という認識でよいでしょうか?
はいそうです。(alive→beingって言うような意味です。)

>・上記内容をネットで見かけたのですが、「AND」は、「WHERE」の前に来てもいいのでしょうか?
「AND]は「WHERE」にかかっているのではなく「LEFT 」の結合の条件となります。
SELECT a.*, b.being_name
FROM alive a
LEFT JOIN being b ON a.hoge_id = b.id
LEFT JOIN call c ON (c.call_id = a.hoge_id AND f.hoge_id = 12)
WHERE f.hoge_id = 12 OR b.id = 12

<<追記>>
このSQLにはfというテーブルが存在しないのでエラーとなります。

Q2つの項目が重複するレコードを抽出する方法はありますか?

MySQL4.1で既存データに対し複合キーを新しく設定したいのですが、

ALTER TABLE `test` ADD PRIMARY KEY (`a`,`b`)

としても重複データが存在する為、作成できませんでした。

10万件あるテーブルから重複するレコードを手動で削除したいのですが、aとbが重複しているレコードだけ抽出するSQL文はありますでしょうか?

Aベストアンサー

select * from `test`
where (a,b) in(
select a,b from `test`
group by a,b
having count(*)>1)

Qシングルクォーテーションとダブルクォーテーション

いつも楽しく拝見させて頂いています。
初心者ですが宜しくお願いします。
シングルクォーテーションとダブルクォーテーションの使用方法について質問させて頂きます。
select文でテーブル名を指定するときはそのまま(たとえば'名前'じゃなく名前)しないとエラーになります。そういう風なシングルクォーテーション(又はダブルクォーテーション)を使ってはいけないところ、またシングルクォーテーションにしないといけないところ、ダブルクォーテーションにしないといけないところを教えて頂けますでしょうか?もし両方OKならその違い等も教えていただけるとうれしいです。
以上宜しくお願いします。

Aベストアンサー

文字定数は、「'」で囲む必要があります。

例)SELECT 'ABC' →文字定数の'ABC'と解釈される
SELECT ABC →ABCは、表名や列名と解釈される

数値定数は、多くのRDBMSでは「'」で囲みませんが、MySQLでは独自仕様として囲むことが可能です。

例)SELECT 123 →数値定数の123
SELECT '123' →一般的なRDBMSでは文字として扱われる。MySQLでは数値としても扱える

殆どのRDBMSには予約語があり、RDBMSでは予約語を頼りに構文解析します。表名や列名に英単語やその組み合わせを使おうとすると、予約語とぶつかってしまうことがあります。

例)SELECT FROM FROM →予約語のSELECT FROMの間に「*」や列名が指定されておらず、RDBMSは構文誤りと認識する

それを回避するために、標準SQLでは「"」で表名や列名を囲みます。MySQLでは、文字コードにANSIを使う場合は、「"」で、それ以外には独自仕様で「`」(バッククォーテーション)を使います。

例)SELECT "FROM " FROM →多くのRDBMSでは「"」で囲むことで、RDBMSに最初の「FROM」は、列などの名前であることを知らせる
SELECT `FROM` FROM →ANSI以外のMySQLでは、「`」(バッククォーテション)で囲む

また、「-」(ハイフォン)を表名や列名に使う場合、「"」で囲まないと、SQLでは減算と解釈されます。このように、「"」で囲むことで、記号なども名前に使用することができます。

例)SELECT ABC-DEF →列ABCと列DEFの減算と解釈される
  SELECT "ABC-DEF" →列「ABC-DEF」と解釈される
  SELECT `ABC-DEF' →ANSI以外のMySQLでは、「"」でなく「`」(バッククォーテション)を使用

文字定数は、「'」で囲む必要があります。

例)SELECT 'ABC' →文字定数の'ABC'と解釈される
SELECT ABC →ABCは、表名や列名と解釈される

数値定数は、多くのRDBMSでは「'」で囲みませんが、MySQLでは独自仕様として囲むことが可能です。

例)SELECT 123 →数値定数の123
SELECT '123' →一般的なRDBMSでは文字として扱われる。MySQLでは数値としても扱える

殆どのRDBMSには予約語があり、RDBMSでは予約語を頼りに構文解析します。表名や列名に英単語やその組み合わせを使おうとすると、予...続きを読む


人気Q&Aランキング