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

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

ただいまの
回答率

87.37%

selectで条件(配列)以外のものを呼び出したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,737

score 12

PHPでレビューサイトを作っています。  

レビューを書いたら、次へのボタンが表示され、クリックするとそのユーザーがレビューを書いたことがないアプリの情報だけが表示されるというシステムなのですが、書いたことがないものだけを呼び出すことができません。

レビューとアプリのテーブルがあります。
ユーザーがレビューを書いたアプリのid(game_id)を呼び出して、アプリのテーブルからnotを使って、game_id以外のアプリのみを呼び出す方法で試したのですが、投稿済みのアプリも表示されてしまいます。

//------ユーザーがレビューを書いたことのあるアプリのidを呼び出す--------

$revexist_sql="SELECT * FROM review WHERE user_name=:user_name";
$rev_exist=$dbh->prepare($revexist_sql);
$rev_exist->execute(['user_name'=>$u_name]);

while($rev_exist_result=$rev_exist->fetch()){
    $rev_id=$rev_exist_result["id"];//レビューid
    $gameid_rev=$rev_exist_result["game_id"];//アプリid

//$gameid_revには5つのアプリidが入っています
}
ここに言語を入力


//------------ユーザーがレビューを投稿してないアプリを呼び出す---------

$gamedetail="SELECT * FROM game WHERE NOT gameid=:gameid LIMIT 1";
$gamedetail_sql=$dbh->prepare($gamedetail);
$gamedetail_sql->execute(['gameid'=>$gameid_rev]);//ユーザーが投稿済みのアプリid
$gamedetail_result=$gamedetail_sql->fetch();

$gamedetail_id=$gamedetail_result["gameid"];//アプリid
$game_name=$gamedetail_result["gamename"];//アプリ名
$game_pt=$gamedetail_result["gamept"];//アプリポイント
$game_topinfo=$gamedetail_result["game_topinfo"];//アプリ簡単説明
$gameinfo=$gamedetail_result["gameinfo"];//アプリ紹介文
$gamedetail_icon=$gamedetail_result["gameicon"];//アプリアイコン画像
$gamedetail_gameimg=$gamedetail_result["gameimg"];//アプリ画像1
$gamedetail_gameimg2=$gamedetail_result["gameimg2"];//アプリ画像2
$gamedetail_gameimg3=$gamedetail_result["gameimg3"];//アプリ画像横
$dl_url=$gamedetail_result["dl_url"];//dlのurl
$category=$gamedetail_result["category"];//アプリカテゴリ

```

試したこと

$gameid_revが配列なので最後の一つしか呼び出せてないのが原因だと思うのですが、5つidが入っている$gameid_rev以外を呼び出すといった記述方法をおしえてください。

またdo_whileでもできるかと思い試してみたのですが、こちらもうまく表示することができませんでした。

そもそも2つともやり方がちがうのか、教えて下さい。
よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • kei344

    2016/10/02 01:26

    質問タグは phpMyAdmin ではなく MariaDB か MySQLではありませんか?また、コードはコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。

    キャンセル

  • puuko

    2016/10/02 03:29

    教えていただいきありがとうございました!

    キャンセル

回答 2

checkベストアンサー

+2

以下のSQL文で取得可能です。

SELECT g.* 
FROM game AS g 
LEFT OUTER JOIN review AS r 
  ON g.gameid = r.game_id AND r.user_name = :user_name 
WHERE r.user_name IS NULL 
LIMIT 1;


http://sqlfiddle.com/#!9/dd4643/1
http://sqlfiddle.com/#!9/dd4643/2
http://sqlfiddle.com/#!9/dd4643/3

ポイントは

  • gameテーブルとreviewテーブルを左外部結合(gameが左)する
  • 結合条件(ON句)にr.user_name = :user_nameを含め、
    全てのアプリに対して対象ユーザーのレビューデータだけを結合する
  • WHERE句にr.user_name IS NULLを指定し、
    ユーザー名が NULL(すなわち、対象ユーザーがレビューしていない)ゲームのデータを取得する

です。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/02 18:55

    どうもありがとうございます!教えていただいた通りにやってみたら未投稿のレビューのみを取得することができました。ポイントもありがとうございます!

    キャンセル

0

SQLは一発でいけそうです。

select
    g.*
 from
     review r join game g
     on r.game_id = g.id
 where
     r.user_name <> :user_name
 limit 1

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/02 03:26

    回答ありがとうございます!
    試してみたのですが、reviewの中でuser_nameが一致しないgameidのみが表示される結果になりました。
    なのでreviewに存在しないgameidは表示されません。

    $gamedetail="SELECT g.* FROM review r join game g on r.game_id!=g.gameid WHERE r.user_name <> :user_name";

    上記で試してみましたが、先ほどとは逆のreview内でそのユーザーが投稿したものではない、gameidが表示される結果となってしまいます。

    こういうやり方があるんだととても勉強になりました。
    教えていただいた方法を参考に、もう少し考えてみます。
    またこうしたみたら?等ありましたら、アドバイスお願いします。

    キャンセル

  • 2016/10/02 03:43

    join のところ、right join にしてみてください。

    キャンセル

  • 2016/10/02 19:00

    遅くなり申し訳ありません。right join でやってみましたが、reviewの中での取得しかできませんでした。joinで行う方法を教えていただいてどうもありがとうございました。

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る