ミスチルの大名曲の数々が配信決定!! 31日間無料!!【PR】

MySQLで複数テーブルからデータ取得する際、
FROMの後に、テーブル名を2つ書いて、「WHERE」で繋げる書き方と、
「JOIN ★★ ON」で繋げる書き方では、何が違うのでしょうか?

・「INNER JOIN」と同じ意味でしょうか?
・書き方によっては、「LEFT OUTER JOIN」みたいにも書けるのでしょうか?

・普通は、どちらの書き方で書くとか、そういうお作法的な暗黙の了解はあるでしょうか?
・例えば「WHERE」だと3つ以上繋げられない(?)から、奨励されていない、とか…

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

A 回答 (2件)

select *


from 表A, 表B
where 表A.列1 = 表B.列2 and 表A.列3 = 値



select *
from 表A inner join 表B on 表A.列1 = 表B.列2
where 表A.列3 = 値

は同じ結果となります。前者の方が古くからある構文,後者が新しい構文になります。新しいといっても20年は経っていますけれど。


> 普通は、どちらの書き方で書くとか、
> そういうお作法的な暗黙の了解はあるでしょうか?

旧構文は,結合を指定する要素がfrom句とwhere句に分かれてしまっているのに対して,
新構文では次のように各句の機能が明確ですから,join句の使用をお薦めします。

射影…select *
結合…from 表A inner join 表B on 表A.列1 = 表B.列2
選択…where 表A.列3 = 値


> 書き方によっては「LEFT OUTER JOIN」みたいにも書けるのでしょうか?

旧構文で外部結合を記述することもできますが,各データベース製品の独自構文になります。標準SQLの規格ではありません。


> 「WHERE」だと3つ以上繋げられない(?)から、奨励されていない、とか

そういう制限はありません。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

>新しいといっても20年は経っていますけれど
・初めて知りました
・大変参考になりましたー

お礼日時:2013/05/22 12:15

>FROMの後に、テーブル名を2つ書いて、「WHERE」で繋げる書き方と、


>「JOIN ★★ ON」で繋げる書き方では、何が違うのでしょうか?
WHEREは古いやり方で、JOIN ONは新しいやり方で、書き方以外の違いは無いと思います。
>「INNER JOIN」と同じ意味でしょうか?
そうです。
>書き方によっては、「LEFT OUTER JOIN」みたいにも書けるのでしょうか?
Oracleの場合(+)を付けて可能ですがMySQLは多分出来ないと思います。
>普通は、どちらの書き方で書くとか、そういうお作法的な暗黙の了解はあるでしょうか?
>例えば「WHERE」だと3つ以上繋げられない(?)から、奨励されていない、とか…
どちらも規格になっているので良いと考えますが、後で見たときにINNER JOINの方が結合の条件がONでのみ確定するので解析しやすいと思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

>Oracleの場合(+)を付けて可能ですがMySQLは多分出来ないと思います
・Oracleに言及している記述は見たことがあるのですが、MySQLに関しては触れられていなかったので、疑問に思っていました
・大変参考になりましたー

お礼日時:2013/05/22 12:18

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

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

このQ&Aを見た人はこんなQ&Aも見ています

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

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

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

QJOINの時のONとWHEREの違いについて

二つのテーブルをjoinして比較したいときに
比較対象の項目がA,Bとあったとします。AはキーですがBはキーではありません。
このとき、ON句でTABLE1.A=TABLE2.A and TABLE1.B=TABLE2.B
とかくのと
ON句でTABLE1.A=TABLE2.A
WHERE TABLE1.B=TABLE2.B
と書くのとで結果に違いはあるのでしょうか?
違いが見つけられずに困っています。
違っていない場合、どちらが一般的でしょうか?

どうぞよろしくお願い致します。

Aベストアンサー

inner joinであれば、どちらも違いはありません。
outer joinであれば、まったく違うものになります。

outer joinの場合、on句の結合条件で偽となる行も、nullとして結果が返されます。また、where句の抽出条件で偽となる行は、最終的な結果としては返されません。

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           ...続きを読む

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.年月 = 任意の値

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

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というテーブルが存在しないのでエラーとなります。

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.区分

QERROR1062:Duplicate entry.....というエラーが出てしまいました

いつもお世話になります。
データベースからSELECTで抽出したデータを別のテーブルにINSERTするSQLを実行したのですが、
ERROR1062:Duplicate entry.....というエラーが出てしまいました。
お詳しい方がいらっしゃいましたら、アドバイスをいただけませんでしょうか?よろしくお願いいたします。
【実行したSQL】
INSERT INTO tblA (dataA1, dataA2, dataA3, dataA4) SELECT "9001","AA",dataB1,dataB2 FROM tblB WHERE dataB1 = 52

tblAの主キー:dataA1とdataA2
tblBの主キー:dataB1

dataA1とdataA2はtblAの主キーとなっているため、重複してしまうということのようです。tblBの主キーはdataB1であるため、抽出されてくるデータは常に1件なので問題ないと期待していましたが、甘くなかったようです。何か良い方法はないものでしょうか?よろしくお願いいたします。

Aベストアンサー

「ERROR 1062」は、重複データを格納しようとした場合に出力されるエラーです。
既にdataA1='9001'&dataA2='AA'という行が、tblAに格納されているのですよね?

>抽出されてくるデータは常に1件なので問題ないと期待していました

「insert ~ select ~」を実行前に、既に同じデータが格納されているのでは?
あるいはprimary keyの指定が、質問中に記された通りでなく、2件以上検索されているかです。

>何か良い方法はないものでしょうか?

何をするための方法を、聞きたいのかが分かりませんが?

Qテーブルの最後(最新)のレコードを抽出したい

宜しくお願いします。
PHP MYSQL の組み合わせで使っています

以下のようにして、最後のレコードを取り出したいのですが
まったく違う事をしているのかもしれません。

$sql =" select * from テーブル where フィールド='max' " ;

フィールドはauto_incrementで番号を振っています。
これで最大のつもりなのですが・・・。

他にも、レコードを入れた時間も記録したフィールドがあるのですが
どうしてよいか?判りません。

テーブルの最新のレコードを出したいのです。
**その中の一つのフィールドを取り出すのですが、
  それはうまくいっているみたいです 
  (max の所に数字を入れると表示します)

お手数かけますが、どなたかご教授お願いいたします。

Aベストアンサー

#2回答者です。

MySQL 4.1以前(サブクエリを使えない)なら、以下のような方法が考えられます。

select * from 表名
order by 列名 desc limit 1

QSELECT文で、指定カラム以外の全カラムを一括指定って可能でしょうか

SELECT文で、指定カラム以外の全カラムを一括指定って可能でしょうか?
MYSQLサーバのバージョンは5.0.77です。

下記のように「*」を使用して指定テーブルの全カラムを表示する方法がありますが、
SELECT TableName.* FROM TableName

上記の逆で、指定テーブルの指定カラム以外の全カラムを一括指定って可能でしょうか?
例えば下記のような「^」みたいな、又は同等な書き方があれば良いなと思ってまして。
SELECT TableName.^ColumnName1 FROM TableName

ちなみに、下記のように一つ一つ表示したいカラムを指定する方法以外です。
SELECT TableName.ColumnName2 , TableName.ColumnName3 FROM TableName

よろしくお願いします。

Aベストアンサー

ない。
SQL文でそんなことをするより、メソッドとして作ればいいんじゃないですか。
だいたい、それ以外のカラムの数がわからないし、並びも不明だし。

#1に方と同じで
SELECT * from xxxx
なんてのは正気の人間は書きません。
カラムの数も位置も属性もわからないSQL文の結果をどうやって扱うのか。

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を使うとか、レコードの更新時刻を突っ込むとか。

QERROR 1054 (42S22) 原因不明です

idはintでプライマリー
a5はchar(10)で日本語文字列を格納

データを取得しようとすると#1054エラーがでます。

admin--------
SELECT * FROM `aaa` WHERE `a5`=`あいうえおかき`
#1054 - Unknown column 'ã

moniter--------
mysql> SELECT * FROM `aaa` WHERE `a5`=`あいうえおかき`;
ERROR 1054 (42S22): Unknown column '縺ゅ>縺・∴縺翫°縺・ in 'where clause'


`あいうえおかき`の日本語に問題があると思い半角データを1行だけ更新しました。
admin--------
SELECT * FROM `aaa` WHERE `a5`=`abcde`
#1054 - Unknown column 'abcde' in 'where clause'

moniter--------
mysql> SELECT * FROM `aaa` WHERE `a5`=`abcde`;
ERROR 1054 (42S22): Unknown column 'abcde' in 'where clause'


admin--------
moniter--------
SELECT * FROM `aaa` WHERE `a5`
SELECT `a5` FROM `aaa` WHERE 1
SELECT * FROM `aaa` WHERE `id`=89584
成功

idはintでプライマリー
a5はchar(10)で日本語文字列を格納

データを取得しようとすると#1054エラーがでます。

admin--------
SELECT * FROM `aaa` WHERE `a5`=`あいうえおかき`
#1054 - Unknown column 'ã

moniter--------
mysql> SELECT * FROM `aaa` WHERE `a5`=`あいうえおかき`;
ERROR 1054 (42S22): Unknown column '縺ゅ>縺・∴縺翫°縺・ in 'where clause'


`あいうえおかき`の日本語に問題があると思い半角データを1行だけ更新しました。
admin--------
SELECT * FROM `aaa` WHERE `a5`=`abcde`
#1054...続きを読む

Aベストアンサー

> SELECT * FROM `aaa` WHERE `a5`=`abcde`

こうしてみるとか:

SELECT * FROM aaa WHERE a5='abcde'

参考:
http://dev.mysql.com/doc/refman/5.1/ja/identifiers.html
http://dev.mysql.com/doc/refman/5.1/ja/string-syntax.html


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング