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

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

ただいまの
回答率

90.46%

  • MySQL

    7167questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • SQL

    3099questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

SNSサイト作成によるSQL文の構造

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 305

YutaNkai

score 61

現在SNSサイトの作成をしておりまして、その際のデーターベースの構造が私の求めている物になっているかご教授のほどよろしくお願いします。以下使用中のテーブルとデータの情報です。SNSサイトですのでツイートテーブルもありますが、ここでは関係がないので省略します。

CREATE TABLE  `user` (
 userid INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 name varchar(100) NOT NULL,
 pass varchar(100) NOT NULL
) ;

INSERT INTO `user` (`name`, `pass`) VALUES
('Chandler', 'temp'), ('Ken', 'temp'), ('Ross', 'temp'), ('Joye', 'temp'), ('Tag', 'temp'),
('Matt', 'temp'), ('Rachel', 'temp'), ('Bob', 'temp'), ('Lisa', 'temp'), ('Hanks', 'temp'),
('Ben', 'temp'), ('Kazu', 'temp'), ('Tobby', 'temp'), ('David', 'temp'), ('Mike', 'temp'),
('Gary', 'temp'), ('Ellen', 'temp'), ('Emilly', 'temp'), ('Carol', 'temp'), ('Frank', 'temp');

CREATE TABLE  `follow` (
 id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 userid int(11) NOT NULL,
 followingid int(11) NOT NULL,
 status int(11) NOT NULL
) ;

INSERT INTO `follow` (`userid`,`followingid`, `status`) VALUES
(1,2,1),(1,3,1),(1,7,1),(1,8,1),(4,3,1),
(4,8,1),(4,7,1),(6,10,1),(7,10,2),(19,20,2),
(8,10,1),(2,3,1);


*followのstatusの値はとなっております。
1申請許可済(友達)
2申請中
3申請却下

質問❶
id  userid  followingid  status
*        1               2          2

のstatusが承認され1となった場合は、userid1とuserid2は友達ということになりますが、
この場合

id  userid  followingid  status
*        2               1          1
と言うuseridが2の行は追加する必要はないと言う認識でよろしいでしょうか。
つまり

id  userid  followingid  status
*        1                2          1
id  userid  followingid  status
*        2                1          1

とする必要はないですよね。

質問❷

『友達かも』リストを作成します。条件は現在使用中ユーザーの友達の、友達を抽出したいのですが以下の文で合っていますか。使用中のユーザはuserid1とします。当然友達ですのでstausは1であるものに限ります。この場合以下のSQL文で合っています。

CREATE TABLE  `user` (
 userid INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 name varchar(100) NOT NULL,
 pass varchar(100) NOT NULL
) ;

INSERT INTO `user` (`name`, `pass`) VALUES
('Chandler', 'temp'), ('Ken', 'temp'), ('Ross', 'temp'), ('Joye', 'temp'), ('Tag', 'temp'),
('Matt', 'temp'), ('Rachel', 'temp'), ('Bob', 'temp'), ('Lisa', 'temp'), ('Hanks', 'temp'),
('Ben', 'temp'), ('Kazu', 'temp'), ('Tobby', 'temp'), ('David', 'temp'), ('Mike', 'temp'),
('Gary', 'temp'), ('Ellen', 'temp'), ('Emilly', 'temp'), ('Carol', 'temp'), ('Frank', 'temp');

CREATE TABLE  `follow` (
 id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 userid int(11) NOT NULL,
 followingid int(11) NOT NULL,
 status int(11) NOT NULL
) ;

INSERT INTO `follow` (`userid`,`followingid`, `status`) VALUES
(1,2,1),(1,3,1),(1,7,1),(1,8,1),(4,3,1),
(4,8,1),(4,7,1),(6,10,1),(7,10,2),(19,20,2),
(8,10,1),(2,3,1);

SELECT * FROM follow
WHERE (userid IN(SELECT followingid FROM follow WHERE userid = 1) OR
followingid IN(SELECT followingid FROM follow WHERE userid = 1))
AND userid NOT IN(1)
ANd status = 1;

質問❸
質問❶の認識が正しい場合、

id  userid  followingid  status
*        1                2          1

という行が存在した場合、

id  userid  followingid  status
*        2                1          1

という行は存在してはいけないことになりますが、userid  followingid をが逆にしたものは同じなので追加出来ないという制御は、カラムの型の様に設定する方法はないでしょうか。つまり追加int型にvarchar型を追加しようとした際にSQL文エラーが出る様な感じです。

【追記❶】

INSERT INTO `follow` (`userid`,`followingidid`, `status`) VALUES
(1,2,1),(1,3,1),(1,7,1),(1,8,1),(4,3,1),
(4,8,1),(4,7,1),(6,10,1),(7,10,2),(19,20,2),
(8,10,1),(2,3,1)(15,1,1),(14,1,1),(13,1,1)
(12,1,1),(11,1,2),(1,9,2);

の関係で使用中ユーザのidが1の場合に『友達かも』として抽出したい値は以下になります。
useridが4,10このつだけになります。

SELECT * FROM user WHERE userid
IN
(SELECT userid FROM follow WHERE followingid = 1 and status = 1
UNION ALL
SELECT followingid FROM follow WHERE userid = 1 and status = 1);

このSQL文を実行すると、1と友達関係にあるuser2,3,7,8,12,13,14,15
が抽出されます。

次に、このユーザーidと友達関係にあるものを、順に見ていきます。(ユーザー1を除く)
2と友達関係にあるのは3のみですが、3既に1と友達関係にあるので必要がありません。
次に3と友達関係にあるのは2ですがこれも同様に1と既に友達関係にあるためいりません。
次に7と友達関係にあるのは4,10です。これはどちらとも1とは友達関係にありませんので、『友達かも』として必要です。

これを全ての数字に割り当てたいのです。どうかご教授のほどよろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+2

ロジック的にちゃんとやるなら

friendテーブルをつくり、friendIDを発行し1IDごとに2ユーザーIDを割り当てることです
各userID毎に申請、応諾、応諾済みなどstatusを付ければ良いと思います

Aさん(ID=1)、Bさん(ID=2)があったとして
Aさんが、Bさんを友達かもしれないとして申請するとき
friendテーブルに2レコード投入します
friendIDを仮に100として

friendID userID status
100 1 1
100 2 0

status:0=不明、1=申請

ここでBさんが拒否したときたとえば
status:99=拒否、98=被拒否

friendID userID status
100 1 98
100 2 99

となり、逆に応諾されたとき
status:2=応諾、3=被応諾

friendID userID status
100 1 3
100 2 2

とすればよいでしょう。
(応諾と被応諾は一緒でもよいかも)

その他statusとして、保留とかブロック(途中から)とか退会とかいろいろ必要になると思います。
いずれにしてもfollowテーブルのようにuseridとfollowingidのような
構造的な主従関係は付けないほうが良いと思います
(また仮に主従関係があるとしてもstatusはそれぞれに対して必要)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/17 17:25

    ありがとうございます。
    friendID userID status
    100 1 1
    100 2 0



    friendID userID status
    100 1 1

    特にsatus 1は何を表しているのですか。

    キャンセル

  • 2018/12/17 17:31

    私の経験不足なのは承知なのですが、
    仮にfriendID100が1,2を管理していたとしてもfriendID200くらいで、2,1を管理するみたいなことが起きる気がします。

    キャンセル

  • 2018/12/17 17:32

    一応status:1=申請中と書いたつもりですが・・・

    ユーザーIDはfrirendIDに対してstatusを持ちます。
    逆にfriendID:100はuserID:1からstatus:1=申請中になります
    その際もう一方のfriendID:100でつながるuserID:2は不明(被申請)状態になります

    キャンセル

  • 2018/12/17 17:36

    > friendID200くらいで、2,1を管理するみたいなことが起きる気がします。

    friendテーブルに登録する際相手との関係が発生しているかどうかチェックしてから
    追加するものですからよほどひどい運用をしなければ競合は発生しないです

    キャンセル

  • 2018/12/17 18:04

    ありがとうがざいます。未だにイメージが掴めないのですが、
    friendIDは当然オートインクリメントでは実現できないですよね。

    キャンセル

  • 2018/12/17 18:09

    工夫次第ですね。
    friendテーブルのレコード特定用にpidをオートインクリメントで用意し
    それを流用する手もあるでしょうし
    いまは要求定義の段階だと思うので、それに合わせて機能を拡張したり
    絞り込んだりする要件定義時点でテーブル構造は決めて下さい

    キャンセル

  • 2018/12/17 18:26

    ありがとうござざいます。
    同じ質問をしましたが、できるだけたくさんの回答を頂きたいだけでございます。大変失礼いたしました。
    回答頂いた様な設計にするメリットは何でしょうか。

    また、私の質問文にあるSQL文の欠点を教えて頂けないでしょうか。何処が不足するので、こういう文の方が適切だ。の様な感じでしょうか。まだ何処がダメなのかわかっておりません。

    キャンセル

  • 2018/12/17 19:18 編集

    じゃあ、解決済みにしてはダメですね。※解決済みは外す事もできるはずです。
    同じ内容での質問を別に立てる事は逆に回答者を遠ざけています。

    キャンセル

  • 2018/12/17 21:09

    ベスアンサーを解除いたしました。不快な思いをさせてしまい大変申しわけありませんでした。
    回答をお待ちしております。

    キャンセル

  • 2018/12/17 21:13

    新しい質問は削除依頼した方が良いかと。

    キャンセル

  • 2018/12/17 21:26

    行いました。よろしくお願いします。

    キャンセル

  • 2018/12/18 16:27

    なにやらいろいろ追加機能の段階に入っているようですが
    今のままであれば

    id userid followingid status
    * 1 2 1
    id userid followingid status
    * 2 1 1
    の両方を設定し、さらにそれが同じであること示す

    id userid followingid status fid
    * 1 2 1 100
    id userid followingid status fid
    * 2 1 1 100

    みたいなことが必要で、これって私が提示したのをぐちゃっと使いにくくしただけの処理ですよ

    キャンセル

  • 2018/12/19 01:42

    ありがとうございます。
    失礼な態度をとったにも関わらず、対応していただき感謝です。

    同じものはひとつにまとめます。
    userid 1 followingid 2 staus 1
    の場合は、これで1と2を管理します。

    SQLの検索、PHPでの表示の関係で
    懸念していた
    userid 2 followingid1 status 1
    がもう一度、はいるということは
    なさそうなので。

    今悩んでおりますのは、
    1が4に申請をした場合、

    userid 1 following4 status 2

    となり、userid4 のユーザが
    ログイン時に友達申請のリクエストがあります。という形で表示させたいのです。

    質問といたしましては

    userid 1 following4 status 2

    という行を例にした場合、この行は
    1と4を管理する行であるが

    申請の関係については
    1が4に申請をした。

    userid 4following1 status 2
    仮にこの様に逆だった場合は
    同じくこの行は4と1を管理する行で有るが、申請は4が1に行った。

    という運用で大丈夫かどうか知りたいです。

    キャンセル

  • 2018/12/19 16:28

    一旦これにて質問を締めさせていただきます。有難うございました。

    キャンセル

checkベストアンサー

+1

1.関係を明確にするために必要とする項目数としては不足は無いと思います。
ですが、ステータスとしては申請取り下げた後だとか退会した後などをどのように表現するかによって不足生じそうな気がします。

2.不足があるんじゃないかと

select * from user
where   userid in (
            select followingid from follow
            where  userid in ( -- 友達が承認された友達
                     select followingid from follow where status=1 and userid=1 -- 承認された友達
                   union all
                     select userid from follow where status=1 and followingid=1 -- 承認した友達
                   )
               and status = 1
          union all
            select userid from follow

            where  followingid in ( -- 友達が承認した友達
                     select followingid from follow where status=1 and userid=1 -- 承認された友達
                   union all
                     select userid from follow where status=1 and followingid=1 -- 承認した友達
                   )
               and status = 1
          union all
            select followingid from follow where status=1 and userid=1 -- 承認された友達
          union all
            select userid from follow where status=1 and followingid=1 -- 承認した友達
        )
   and  userid NOT IN(1)


3.この構造で逆の組み合わせの一意制約は無理ですね、

MySQL 5.7で生成カラムを使ってCHECK制約もどきを実装する

追記

「友達かも」リストについては、事象を分けて考えれば、そんなに難しい事ではありません

select * from user
where   userid in (
            select followingid from follow
            where  userid in ( -- 友達が承認された友達
                     select followingid from follow where status=1 and userid=1 -- 承認された友達
                   union all
                     select userid from follow where status=1 and followingid=1 -- 承認した友達
                   )
               and status = 1
          union all
            select userid from follow

            where  followingid in ( -- 友達が承認した友達
                     select followingid from follow where status=1 and userid=1 -- 承認された友達
                   union all
                     select userid from follow where status=1 and followingid=1 -- 承認した友達
                   )
               and status = 1
        )
   and  userid NOT IN(1) -- 起点のユーザー
   and  userid not in ( -- 友達
            select followingid from follow where status=1 and userid=1 -- 承認された友達
          union all
            select userid from follow where status=1 and followingid=1 -- 承認した友達
       )


ただ、unionしないと駄目な時点で、正規化からは外れています。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/17 18:00

    ありがとうございmす。
    では3についてですが、それは私たちの操作側が
    id userid followingid status
    * 1 2 1

    があれば、

    id userid followingid status
    * 2 1 1

    という反対の値が起こらないようにすれば良いということですか。

    キャンセル

  • 2018/12/17 18:04

    追記しました。
    ※なんか同じ質問が上がっているようですけど???

    キャンセル

  • 2018/12/17 18:12 編集

    中途半端に質問をしめて、同じ内容で聞かれるのって
    結局「あなたの意見は参考にならなかったのでもう回答いらない」
    という意思表示に見えますよね、なんか残念。

    キャンセル

  • 2018/12/17 21:36

    提示して頂いたSQL文がエラーになってしまいます。
    自分で修正はしましたが、エラーが消えません。

    エラー文
    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 8

    実行文

    select * from user
    where userid in (select followingid from follow
    where userid in (select followingid from follow where status=1 and userid=1 union all select userid from follow where status=1 and followingid=1) and status = 1

    union all

    select userid from follow
    where followingid in (select followingid from follow where status=1 and userid=1 union all select userid from follow where status=1 and followingid=1 and status = 1) and userid NOT IN(1);

    キャンセル

  • 2018/12/18 00:40

    項目名を誤っている箇所は修正しました。修正後ではこちらではエラーなりません。
    もう一度確認してみて下さい。

    キャンセル

  • 2018/12/18 03:54

    お付き合いありがとうございます。頂いたSQL文は問題ありませんでした。ありがとうございます。
    テーブル情報に値を追加いたしました。

    INSERT INTO `follow` (`userid`,`followingidid`, `status`) VALUES
    (1,2,1),(1,3,1),(1,7,1),(1,8,1),(4,3,1),
    (4,8,1),(4,7,1),(6,10,1),(7,10,2),(19,20,2),
    (8,10,1),(2,3,1)(15,1,1),(14,1,1),(13,1,1)
    (12,1,1),(11,1,2),(1,9,2);

    現在は、この様な値です。

    質問が2つあります


    SELECT * FROM user WHERE userid
    IN
    (SELECT userid FROM follow WHERE followingid = 1 and status = 1
    UNION ALL
    SELECT followingid FROM follow WHERE userid = 1 and status = 1);

    このSQL文に問題はありますか。同じ値がきちんと返ってきます。


    質問文で述べた機能
    『友達かも』『友達リクエスト』は現在のfollowテーブル

    id userid followingid status

    で運用できる気がします。(退会等はとりあえず置いておきます)

    そもそも、友達リクエストも

    id userid followingid status
    * 1 2 1

    といのが存在する場合、2は1に対して友達申請が送れない様にSQL文をSELECTとしていくわけですから
    id userid followingid status
    * 2 1 1

    この様に2が二重に友達申請をすることはありえない気がします。
    そもそもstatusがすでに1の場合はHTMLで表示しない様にするわけですし。

    どうでしょうか。現在作成中ですが特に問題は現在はですが、ありません。

    キャンセル

  • 2018/12/18 09:29

    1.「友達」の範囲ですね。質問には「友達の友達」とありましたけど?
    2.制限付けるなら問題ないのではないでしょうか。
     そもそも処理で制約付けるんなら、定義での制約など求める必要ないですね。

    キャンセル

  • 2018/12/18 10:52

    ありがとうございます。だいぶ見えてきました。

    1.はい友達の友達でございます。
    問題ありでしょうか。

    キャンセル

  • 2018/12/18 10:58

    データ上、「友達の友達」でしか抽出できないパターンがあった場合、ネストが不足すると抽出できないと思いますけど。

    キャンセル

  • 2018/12/18 11:14

    ありがとうございます。
    常に

    友達の友達で抽出するのではないのでしょうか。

    理解不足ですがよろしくお願いします。また、お付き合い頂いておりますこと、感謝しております。

    キャンセル

  • 2018/12/18 11:21

    データまで詳しく見てないのですが、userid=1からみて「友達の友達」の関係となるfollowのデータはどれですか?

    キャンセル

  • 2018/12/18 12:54 編集

    私の勘違いでした。私のだと単なる「友達」の抽出ですね。
    「友達かも」の定義なのですが、
    友達の友達であり、かつその友達が自分とすでに友達であってはいけないという定義です。

    AB
    BC
    AC

    という友達関係が成立していた場合、CはAからみて
    B(友達)の友達に当たりますが、既にAとCは友達ですので、表示させません。

    ご回答いただいたSQL文では
    既にuserid1の友達である、2,3,14,15などが表示されています。

    ご教授の程よろしくお願いいたします。

    キャンセル

  • 2018/12/18 13:12 編集

    条件としているのは関係があるかどうかです。途中の組み合わせを求める必要があるのですか?
    私の提示しているSQLはfollowは表示していませんが?

    キャンセル

  • 2018/12/18 14:48

    ありがとうございます。
    頂いたのは、ユーザーの情報です。

    先程、回答いたしました条件を満たすユーザー番号が必要になると考えております。

    キャンセル

  • 2018/12/18 15:06 編集

    友達の友達から友達を除くという事ですか?
    イメージ合わせのために、抽出したい結果のデータサンプルを質問に追記して下さい。

    キャンセル

  • 2018/12/18 16:23

    質問更新致しました。
    【❶追記】としてあります。

    キャンセル

  • 2018/12/18 16:30

    いつの間に「友達かも」が主題になったのでしょう?
    質問のSQLでは掠りもしていませんけど・・・
    「友達かも」のみが必要なんでしょうか?
    「友達かも」の条件は、「友達の友達」かつ「友達でない」ですよね?

    キャンセル

  • 2018/12/18 16:38

    左様でございます。友達の友達」かつ「友達でない」です。

    キャンセル

  • 2018/12/18 17:07

    お疲れ様です。抽出できたと思います。
    試験的に行ったので、NOT IN句には実数(ユーザー1と友達のユーザーid)を入れております。
    理論的にはあっておりますか。

    SELECT * FROM user WHERE userid IN(

    SELECT userid FROM follow WHERE followingid IN (SELECT userid FROM follow WHERE followingid = 1 and status = 1 UNION ALL SELECT followingid FROM follow WHERE userid = 1 and status = 1)
    AND userid NOT IN (2,3,7,8,12,13,14,15)
    UNION ALL
    SELECT followingid FROM follow WHERE userid IN (SELECT userid FROM follow WHERE followingid = 1 and status = 1 UNION ALL SELECT followingid FROM follow WHERE userid = 1 and status = 1)
    AND followingid NOT IN (2,3,7,8,12,13,14,15)
    )

    AND userid NOT IN (1);

    キャンセル

  • 2018/12/18 17:08

    動作確認済みでございます。

    キャンセル

  • 2018/12/18 17:16

    UNIONとINは効率悪いですが大丈夫ですか?

    キャンセル

  • 2018/12/18 17:20

    ちょっと記述間違えているようですし、条件としては別物でしょう。
    実際に展開すると冗長な記述になりますし、statusとかもう無視してますし。
    結果的に同じに過ぎないだけだと思います。

    キャンセル

  • 2018/12/18 17:24 編集

    > yambeさん
    union はallですからそれほどではないと思いますけど、not inはexistsにした方が良さそうですね。

    一番効率良いのはCTEと再帰だと思いますけど、8.0以降ですしね。

    キャンセル

  • 2018/12/18 17:32

    statusとかもう無視してますし。
    statusは無視してないと思うのですが。
    よろしくお願いします。

    キャンセル

  • 2018/12/18 17:35

    提示したSQLと見比べてください。

    キャンセル

  • 2018/12/18 17:39

    お付き合いありがとうございます。感謝です。
    SELECT * FROM user WHERE userid IN(

    SELECT userid AS maykonw FROM follow WHERE followingid IN (SELECT userid FROM follow WHERE followingid = 1 and status = 1 UNION ALL SELECT followingid FROM follow WHERE userid = 1 and status = 1)
    AND userid NOT IN (SELECT userid FROM follow WHERE followingid = 1 and status = 1 UNION ALL SELECT followingid FROM follow WHERE userid = 1 and status = 1) AND status =1
    UNION ALL

    SELECT followingid AS maykonw FROM follow WHERE userid IN (SELECT userid FROM follow WHERE followingid = 1 and status = 1 UNION ALL SELECT followingid FROM follow WHERE userid = 1 and status = 1)
    AND followingid NOT IN (SELECT userid FROM follow WHERE followingid = 1 and status = 1 UNION ALL SELECT followingid FROM follow WHERE userid = 1 and status = 1) AND status =1
    )

    AND userid NOT IN (1);
    こちらでどうですか

    キャンセル

  • 2018/12/18 18:03

    そのSQLの条件を文章で表してみてもらえます?

    キャンセル

  • 2018/12/18 18:14

    友達がフォローしている友達で、友達でないユーザー

    友達にフォローされていない友達が、フォローしているユーザー
    となるので、followでみると同じデータを指す事がある気がします。

    キャンセル

  • 2018/12/18 21:36

    ありがとうございます。
    SQLの条件は
    友達の友達」かつ「友達でない」。

    で同じでございます。
    現在のところは問題が生じてはいませんが、発生次第確認していきます。

    キャンセル

  • 2018/12/18 23:34

    すみません。追記で確認したいことがございます。

    userid1がuserid4に友達申請を送った時、挿入は
    userid 1、 followingid 4、status2 となる訳ですが、

    この場合、リクエストの判定を下すのは、userid4のユーザーですので
    4の画面にのみ、その通知を出します。

    userid 1、 followingid 4の場合は1が4に申請をした。逆に
    userid 4、 followingid1の場合はは4が1に申請をしたという風に運用していけば問題ないでしょうか。

    キャンセル

  • 2018/12/18 23:51

    逆の組合せはチェックで弾くと言ってませんでしたか?
    整理できていない断片的な内容で質問して回答貰っても、余計に混乱するだけだと思いますよ。
    少し腰を落ち着けて考えてみて下さい。

    それから、項目の名称からは、useridに対してフォローしているのがfollowingidとした方が、直感的だと思えるのですが。

    キャンセル

  • 2018/12/19 01:10

    ありがとうございます。

    逆の組み合わせに関しては、

    PHPの表示非表示の段階でチェックができると考えております。

    ですので、このテーブル設計で進めた場合、

    私の直近の質問の考え方で大丈夫かどうか、少し意見を頂戴したく思いました。

    キャンセル

  • 2018/12/19 16:28

    一旦これにて質問を締めさせていただきます。有難うございました。

    キャンセル

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

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

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

  • MySQL

    7167questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • SQL

    3099questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。