- PR -

[MySQL] クエリの結果が明らかに正しくない

投稿者投稿内容
Tasuku
大ベテラン
会議室デビュー日: 2006/09/14
投稿数: 106
お住まい・勤務地: tokyo
投稿日時: 2006-09-15 22:06
ukさん、末記人さん、ありがとうございます

debugをお願いするようで恐縮ですが。。。

発行しているSQLと、結果をfetch_arrayしたものをupします。
正しい結果は、[1]のみで、[2]...[4]は意図しない結果です。
VR_HOSTS.uid IS NULL は常に偽となるダミー条件です。

コード:

SELECT VR_HOSTS.uid,
VR_HOSTS.address,
VR_HOSTS_NAME_NAME.name,
VR_HOSTS_NAME_CANONICAL.name AS name_canonical
FROM VR_HOSTS
LEFT JOIN VR_HOSTS_NAME AS VR_HOSTS_NAME_NAME
ON VR_HOSTS.uid = VR_HOSTS_NAME_NAME.uid_VR_HOSTS
LEFT JOIN VR_HOSTS_NAME AS VR_HOSTS_NAME_CANONICAL
ON VR_HOSTS.uid = VR_HOSTS_NAME_CANONICAL.uid_VR_HOSTS
WHERE VR_HOSTS_NAME_CANONICAL.canonical IS NULL
AND ( VR_HOSTS.uid IS NULL
OR VR_HOSTS_NAME_NAME.name LIKE '%www.tv-asahi.co.jp%'
)
ORDER BY VR_HOSTS.address
LIMIT 0, 8



コード:

Array
(
[1] => Array
(
[0] => 206
[uid] => 206
[1] => 738057254
[address] => 738057254
[2] => http://www.tv-asahi.co.jp
[name] => http://www.tv-asahi.co.jp
[3] => host220-38.accelia.net
[name_canonical] => host220-38.accelia.net
)
[2] => Array
(
[0] => 94
[uid] => 94
[1] => 1113982867
[address] => 1113982867
[2] => 66.102.7.147
[name] => 66.102.7.147
[3] => 66.102.7.147
[name_canonical] => 66.102.7.147
)
[3] => Array
(
[0] => 94
[uid] => 94
[1] => 1113982867
[address] => 1113982867
[2] => http://www.google.co.jp
[name] => http://www.google.co.jp
[3] => 66.102.7.147
[name_canonical] => 66.102.7.147
)
[4] => Array
(
[0] => 94
[uid] => 94
[1] => 1113982867
[address] => 1113982867
[2] => http://www.google.com
[name] => http://www.google.com
[3] => 66.102.7.147
[name_canonical] => 66.102.7.147
)
)





[ メッセージ編集済み 編集者: Tasuku 編集日時 2006-09-15 22:08 ]
大ベテラン
会議室デビュー日: 2006/06/28
投稿数: 116
投稿日時: 2006-09-15 23:29
MySQLを使用したことがないので詳細不明ですが、記述されたSQL文を参照すると、やりたいこととして先に記述されていたものは実現できそうに見えません。
コード:
OR VR_HOSTS_NAME_NAME.name           LIKE '%www.tv-asahi.co.jp%'


を条件として有効にしたいなら、左外部結合は使用してはまずいのではないでしょうか?

あと、なぜ2度目で上手くいったのかは想像の域を出ませんが、私でしたら
テーブルロックの関係などでファントムリードが発生したことを疑います。
トランザクションについては、マニュアルからするとMySQLもデフォルトではオートコミットを行うようです。
末記人
大ベテラン
会議室デビュー日: 2005/12/05
投稿数: 233
お住まい・勤務地: あわにこ
投稿日時: 2006-09-16 03:09
こんばんは

VR_HOSTSが軸になる抽出のようですが、外部結合の場合きちんと絞込みの条件を
つけないとVR_HOSTS全件分が抽出されてしまうのでは?
WHERE句に書いた VR_HOSTS_NAME_NAME.name like '%略%' は結合するテーブル(VR_HOSTS_NAME_NAME)の抽出条件にであってVRHOSTSには利かないですよ。

あと一意に特定できないテーブル同士を結合すると同じレコードが複数出てきてしまうこともよくあります。
テーブルの設計も見直したほうがいいような希ガス
※条件で一意にならないテーブルAの件数×条件で一意にならないテーブルBの件数

[ メッセージ編集済み 編集者: 末記人 編集日時 2006-09-16 03:10 ]
Tasuku
大ベテラン
会議室デビュー日: 2006/09/14
投稿数: 106
お住まい・勤務地: tokyo
投稿日時: 2006-09-16 08:50
暁さん・未記入さん
ありがとうございます

検索条件が左外部結合の結合側に設定されている点ですが、結果が複数応答
されること自体は、意図したものです。

# www.tv-asahi.co.jp の IPアドレス(複数もあり)を検索。
# そもそもこれ自体が、RDBのQUERYとして禁じ手ということでしょうか。。。

WHERE句の中で、「VR_HOSTS.uid IS NULL」が常に偽であるとき、実質的に
有効な条件は、@ VR_HOSTS_NAME_CANONICAL.canonical IS NULL かつ
A VR_HOSTS_NAME_NAME.name LIKE '%www.tv-asahi.co.jp%' になると
思うのですが、少なくともAに合致しない www.google.com が応答される
点が解せないところです。。。

コード:
WHERE       VR_HOSTS_NAME_CANONICAL.canonical IS   NULL
      AND ( VR_HOSTS.uid                      IS   NULL
         OR VR_HOSTS_NAME_NAME.name           LIKE '%www.tv-asahi.co.jp%'
          )



ファントムリードの件ですが、サンプルの例ですと、この処理の間に、
googleレコードを削除しているということはありません。
Tasuku
大ベテラン
会議室デビュー日: 2006/09/14
投稿数: 106
お住まい・勤務地: tokyo
投稿日時: 2006-09-16 09:11
その後、PHPの側のソースを以下の様に修正したところ(SQLはそのまま)、
事象自体は発生しなくなりました。

コード:
別テーブル1へのSELECT
問題のSELECT
別テーブル2へのSELECT


↓単に実行順序を入れ替えただけです
コード:
別テーブル1へのSELECT
別テーブル2へのSELECT
問題のSELECT



実用上は問題なくなったのですが、原因は今もって不明です。
PHP自体 or 僕のコードの問題なんですかね。。。

ご協力頂いた皆様、ありがとうございます。

# 引き続き、検体として提供できる情報は提供させていただきたいと思います。。。
大ベテラン
会議室デビュー日: 2006/06/28
投稿数: 116
投稿日時: 2006-09-16 12:08
先レスでの記述はトランザクションが怪しいという先入観があった上、MySQLでのSQL記述を見慣れておらず、条件処理順を勘違いしたため間違っていたようです。すみません。
where句が先に評価されると思ってしまったのです。
ORACLE用SQLに書き直した際、勘違いに初めて気づきました。

ファントムリード云々は先の勘違いが元になっているので気にしないでください。
1回目のselectではnameのLIKE条件にマッチしなかったが、2回目までに更新がcommitされマッチするようになったと考えたのです。前提が誤っていたため誤りですが。

もしかしたら、という情報をこちらで見つけました。
4.1でも解決していないバグの中に以下の記述があります。
引用:
同じクエリ内で多数の RIGHT JOINS を連結した場合や LEFT および RIGHT 結合を組み合わせた場合、LEFT 結合の前のテーブルまたは RIGHT 結合の前のテーブルについて NULL 行のみが生成されるので、正しい結果が得られないことがある。これは、FROM 部におけるかっこのサポートの追加と同時に、5.0 で修正する予定である。


正しい結果が得られないことがある……ってどんなとき得られなくなるのだろう?

スキルアップ/キャリアアップ(JOB@IT)