質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.01%

SQLでSELECTの結果が出ない(空)

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,622

hideki0227

score 17

以下のクエリを実行すると、エラーではなく返り値が空になります。なぜでしょうか?
WHERE以降の条件にあてはまるレコードは複数存在しているのですが、何もあてはまりません。
掲示板のようなものなのですが、PHPのプログラム上では投稿がゼロに、phpMyAdminでこのクエリを直接入れると返り値が空です。
関係ない部分も多いかもしれませんが、クエリ全文を載せます。

SELECT 
tw_timeline.number, 
tw_timeline.id, 
tw_timeline.comment, 
tw_timeline.date, 
tw_timeline.replyto, 
tw_timeline.replyfrom, 
tw_timeline.quote_from, 
tw_account_detail.name, 
tw_account_detail.filename, 
quote_replyfrom.id AS quote_id, 
quote_replyfrom.comment AS quote_comment, 
quote_replyfrom.date AS quote_date, 
quote_quote_from.id AS quote_id, 
quote_quote_from.comment AS quote_comment, 
quote_quote_from.date AS quote_date, 
quote_detail.name AS quote_name, 
quote_detail.filename AS quote_filename 
FROM tw_timeline JOIN tw_account_detail ON tw_timeline.id = tw_account_detail.id 
JOIN tw_timeline AS quote_replyfrom ON quote_replyfrom.number = tw_timeline.replyfrom 
JOIN tw_timeline AS quote_quote_from ON quote_quote_from.number = tw_timeline.quote_from 
JOIN tw_account_detail AS quote_detail ON quote_detail.id = tw_timeline.id 
WHERE tw_timeline.id = 1 OR tw_timeline.id = 9 OR tw_timeline.id = 10 OR 
tw_timeline.id = 4 OR tw_timeline.id = 2 OR tw_timeline.id = 3 
ORDER BY tw_timeline.date DESC

tw_timeline(掲示板の投稿内容一覧)というテーブルがありまして、tw_account_detailというのは投稿者の名前などを格納するテーブルです。
同じtw_timelineおよびtw_account_detailのテーブルを2回ずつJOINしているのは、=の右の数値を条件に別の数値を取り出したいためです。

tw_timelineには以下のカラムが、
numberidcommentdatereplytoreplyfromquote_from
tw_account_detailには以下のカラムがあります。
idnameprofplacefilenamecreated_dateupdated_date

例えば各テーブルの1レコード目は以下のようなデータがあります。

tw_timeline

number
id
comment
date
replyto
replyfrom
quote_from

1
3
あいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえお
2016-07-25 17:29:25
0
0
0

tw_account_detail

id
name
prof
place
filename
created_date
updated_date

1
ひろし
ひろしの自己紹介2
東京2
e371bda7e8f2c361cb62978106696603.jpg
2016-09-19 05:01:36
NULL

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    退会済みユーザー

    2016/09/22 15:02

    そもそもデータがないので答えではないのですが。

    あなたの考えている結果を返すSQLでないから件数が0なのです

    キャンセル

  • hideki0227

    2016/09/22 15:13

    追記しましたが、これでわかることはありますでしょうか?

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2016/09/22 15:19

    カラム構造ではなくデータですね。

    [ INNER ] JOIN なので全部にデータがある想定だとおもいますが

    キャンセル

回答 5

checkベストアンサー

+1

多分 LEFT JOIN の感覚で INNER JOIN を使ってるのだと思われる。

SELECT 
  tw_timeline.number, 
  tw_timeline.id, 
  tw_timeline.comment, 
  tw_timeline.date, 
  tw_timeline.replyto, 
  tw_timeline.replyfrom, 
  tw_timeline.quote_from, 
  tw_account_detail.name, 
  tw_account_detail.filename, 
  quote_replyfrom.id AS quote_id, 
  quote_replyfrom.comment AS quote_comment, 
  quote_replyfrom.date AS quote_date, 
  quote_quote_from.id AS quote_id, 
  quote_quote_from.comment AS quote_comment, 
  quote_quote_from.date AS quote_date, 
  quote_detail.name AS quote_name, 
  quote_detail.filename AS quote_filename 
FROM 
  tw_timeline 
  LEFT JOIN tw_account_detail 
    ON tw_timeline.id = tw_account_detail.id 
  LEFT JOIN tw_timeline AS quote_replyfrom 
    ON quote_replyfrom.number = tw_timeline.replyfrom 
  LEFT JOIN tw_timeline AS quote_quote_from 
    ON quote_quote_from.number = tw_timeline.quote_from 
  LEFT JOIN tw_account_detail AS quote_detail 
    ON quote_detail.id = tw_timeline.id 
WHERE 
  tw_timeline.id = 1 
  OR tw_timeline.id = 9 
  OR tw_timeline.id = 10 
  OR tw_timeline.id = 4 
  OR tw_timeline.id = 2 
  OR tw_timeline.id = 3 
ORDER BY 
  tw_timeline.date DESC

で発行したらどうでしょう?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/22 15:53

    ※ 抽出するためだけの条件変更のため ON 句は変更してません。
      不正なデータが複数でます。

    キャンセル

  • 2016/09/23 05:26

    LEFTを追加したら望む通りの挙動になりました(一部ASの使い方などで間違いがあったのでそれらも変えました)。
    ありがとうございます。解決しました。
    私自身JOINとLEFT JOINの違いの理解が曖昧なので、ちゃんと調べてみます。

    ↓最終的なクエリ(★=変更箇所)
    ----------------------------------------
    SELECT
    tw_timeline.number,
    tw_timeline.id,
    tw_timeline.comment,
    tw_timeline.date,
    tw_timeline.replyto,
    tw_timeline.replyfrom,
    tw_timeline.quote_from,
    tw_account_detail.name,
    tw_account_detail.filename,
    quote_replyfrom.id AS quote_replyfrom_id,
    quote_replyfrom.comment AS quote_replyfrom_comment,
    quote_replyfrom.date AS quote_replyfrom_date,
    quote_quote_from.id AS quote_quote_from_id,
    quote_quote_from.comment AS quote_quote_from_comment,
    quote_quote_from.date AS quote_quote_from_date,
    quote_replyfrom_detail.name AS quote_replyfrom_detail_name, ★
    quote_replyfrom_detail.filename AS quote_replyfrom_detail_filename, ★
    quote_quote_from_detail.name AS quote_quote_from_detail_name, ★
    quote_quote_from_detail.filename AS quote_quote_from_detail_filename ★
    FROM tw_timeline LEFT JOIN tw_account_detail ON tw_timeline.id = tw_account_detail.id
    LEFT JOIN tw_timeline AS quote_replyfrom ON quote_replyfrom.number = tw_timeline.replyfrom ★
    LEFT JOIN tw_timeline AS quote_quote_from ON quote_quote_from.number = tw_timeline.quote_from ★
    LEFT JOIN tw_account_detail AS quote_quote_from_detail ON quote_quote_from_detail.id = quote_quote_from.id ★
    LEFT JOIN tw_account_detail AS quote_replyfrom_detail ON quote_replyfrom_detail.id = quote_replyfrom.id ★
    WHERE tw_timeline.id = 1
    OR tw_timeline.id = 9
    OR tw_timeline.id = 10
    OR tw_timeline.id = 4
    OR tw_timeline.id = 2
    OR tw_timeline.id = 3
    ORDER BY tw_timeline.date DESC
    ----------------------------------------

    キャンセル

0

とりあえずtw_timelineに対して同様の条件でSELECTしてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/23 05:32

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

    キャンセル

0

SQLしかタグがありませんが、DBやそのバージョンによって書き方が違うこともありますから、明記した方が良いです。

そもそも、データが1件入っていないか、ON, WHEREを満たすデータがないのかもしれません。
条件を少しずつ削って実行されては?
DBによっては
SELECT COUNT(*) FROM TABLE_NAME1 ;
で指定したテーブルのレコード件数を取得できます。
また、
WHERE tw_timeline.id in(1, 9, 10, 4, 2, 3)
って書き方ができます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/23 05:32

    なるほど。次回からはちゃんと書こうと思います。
    WHERE tw_timeline.id in(1, 9, 10, 4, 2, 3) の書き方も勉強になりました。
    ありがとうございました。

    キャンセル

0

出ている情報だけでは確たることは言えませんね。
tw_timelineテーブルの「number,replyfrom,quote_from」は同じデータ型でしょうか?
やっている事はこの3つが同じでIDが1,2,3,4,9,10のレコードを抜き出しているのだと思いますが、そういったレコードは本当に存在しますか?
次のSQLでも抽出レコード数は同じになるはずです。(1以上が出力されますか?)

SELECT count(*) 
FROM tw_timeline 
WHERE id in(1, 9, 10, 4, 2, 3)
AND number = replyfrom 
AND number = quote_from

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/23 05:31

    そうやって原因の範囲を狭めていくんですね。勉強になりました。
    ありがとうございました。

    キャンセル

0

件数が0の理由がJOINなのかwhereなのかを切り分たいので、where区抜きでidに(1,9,10,4,2,3)が有るかを調べて、その時点で0件であればJOINの条件にて発生している事になります。件数が出ればWHERE条件が足りないとなります。

またFROM tw_timeline JOIN tw_account_detail ON tw_timeline.id = tw_account_detail.idのラインとJOIN tw_account_detail AS quote_detail ON quote_detail.id = tw_timeline.idが同じなので不要では無いかと、有っても問題ありませんが。

訂正:IDが1:nの場合は問題ありますね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/23 05:28

    ありがとうございます。
    後半の重複はおっしゃる通りだったので直しました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる