2011-08-01 13 views
1

PHPといくつかのクエリで簡単に解決できる問題がありますが、 。小さな問題から1つ大きいクエリを作成する問題

だから私は3つのテーブルを持っており、それらいくつかを簡素化しましょう:3列

  • ID
  • のuser_id
  • 2列があり、視認性

accessを持って

topic

  • があれば、ユーザは(私たちは呼んで2列

    • のuser_id
    • は私が何をしたいのか

    をfriend_idたのuser_id

friendshipがある

  • をtopic_id彼のwatch_id)はこのトピックを見ていますI彼が見ることが許されている場合、または彼がそうでない場合、何も返されない場合、トピックを返すことを望みます。 場合 彼は、これらのいずれかが真で視聴することが許可されている:USER_ID

    • watch_id ==
    • 視認== 3
    • 可視性== 2 & &友情テーブルは、行とき友情を返します。 USER_ID = topic.user_id & & friendship.friend_idは==アクセス・テーブルが場合access.topic行を返す
    • 可視== 1 & &をwatch_idあなたはそれがPHPとクエリの束が、SQLにのみ、私はそれを把握することができないで行うには非常に難しいことではありません見ることができるように_id = topic.id & & access.user_id ==は

    をwatch_id。私はジョイン、ケース、物事を試してきましたが、論理は決して合わない。 :(

    だから君たちは私を助けることができるまたは私はPHPとクエリの多くで立ち往生しています

    編集:??!私は私の悪い、自分が完全に明らかにしていなかったよううーん、見える彼はに許可されています

  • 答えて

    3

    あなたは左を作ることができるはずです

    select something 
    from topic 
    left join friendship on friendship.user_id = topic.user_id && friendship.friend_id == watch_id 
    left join access on access.topic_id = topic.id && access.user_id == watch_id 
    where 
        watch_id == topic.user_id or 
        topic.visibility == 3 or 
        (topic.visiblity == 2 and friendship.user_id is not null) or 
        (visibility == 1 && access.topic_id is not null) 
    
    +0

    私は実際にあなたの最高のソリューションを好きでした!それは最も簡単に拡張できます:)ありがとう! – Vejto

    0

    これは1つのクエリでは可能かもしれませんが、最も簡単なのはUNIONを使用することでしょう。さまざまな要件の結果を組み合わせてください。

    SELECT t.* 
    FROM topic AS t 
    WHERE t.user_id = @watch_id AND t.visibility = 3 
    UNION ALL 
    SELECT t.* 
    FROM topic AS t 
         INNER JOIN friendship AS f ON f.user_id = t.user_id 
    WHERE f.friend_id_id = @watch_id AND t.visibility = 2 
    UNION ALL 
    SELECT t.* 
    FROM topic AS t 
         INNER JOIN access AS a ON a.topic_id = t.id 
    WHERE a.user_id = @watch_id AND t.visibility = 1 
    
    0

    あなたはあなたが欲しいトピックを取り戻すために3つの結果セットに労働組合を行い検討することもでき、その後必要なものを返す3つの別々のクエリを持っている場合。

    基本的には、ユーザーが見ることができるすべてのトピックのリストを返す必要があります。

    select t.topic_id 
    from topic as t 
    where t.user_id = watch_id 
    and t.visibility = 3 
        union 
    select t.topic_id 
    from topic as t 
    inner join friendship as f 
    on  f.user_id = t.user_id 
    where f.friend_id = watch_id 
    and t.visibility = 2 
        union 
    select t.topic_id 
    from topic as t 
    inner join access as a 
    on  a.topic_id = t.id 
    where a.user_id = watch_id 
    and t.visibility = 1 
    

    あなたが必要とするものを得るためには、それを使用できるはずです。

    あなたはtopic_idは、上記の結果の中に含まれているかどうかを確認することになります与えtopic_idは、その後、鑑賞することができるかどうかを確認することができますプロシージャまたは関数が必要な場合は設定

    0

    は、サブクエリをお試しください:

    select topic.* from topic 
    where (topic.user_id = watch_id and visibility=3) or 
         (topic.user_id = watch_id and visibility=2 and (select count(*) from friendship where friendship.user_id = topic.user_id and friendship_id = watch_id) > 0) or 
         (topic.user_id = watch_id and visibility=1 and (select count(*) from access where access.topic_id = topic.id and access.user_id = watch_id) > 0) 
    

    このように自ら参加し、結果を制限しないように、友情とアクセステーブルに対して合流lutionは、複数の友人関係やアクセス項目があっても、単一のトピックを許可します。あなたの質問を見て、私は、topic.user_idは3つすべてのwatch_idに等しくなければならないと仮定しましたが、私は間違っている可能性があります。

    ただし、3つのテーブルの間に1対1の関係が存在する場合は、左結合が必要です。

    関連する問題