MySQL-レコードがテーブルFで見つからなかった場合は、リレーショナルテーブルA、B、C、D、Eからデータを選択します

B_CooperA

:私は私のデータベースに6つのテーブルを持っているuserscoursesusers_courseslecturesusers_lecturesattends見出しでは、私はそれらをA、B、C、D、E、Fと呼びました。

学校のプロジェクトの一環として講義の出席システムを作成していますが、ユーザーがまだ出席していない講義のみを選択するクエリを実行する必要があります。

usersテーブルはユーザーに関する情報を保持します。そのテーブル構造は次のとおりです。

id INT(10) USINGNED PRIMARY KEY AUTO_INCREMENT
name VARCHAR(255)
email VARCHAR(255)
password VARCHAR(60)
created_at TIMESTAMP
updated_at TIMESTAMP

coursestableは、講義が属するコースに関する情報を保持する講義の親テーブルです。そのテーブル構造は次のとおりです。

id  INT(10) UNSIGNED AUTO_INCREMENT
name VARCHAR(255)
created_at TIMESTAMP
updated_at TIMESTAMP

users_coursesユーザーとコース間の関係テーブルです。ユーザーをコースにリンクします。そのテーブル構造は次のとおりです。

user_id INT(10) UNSIGNED FOREIGN KEY
course_id INT(10) UNSIGNED FOREIGN KEY

lectures表には、ユーザーが参加する予定の今後の講義に関する情報が含まれています。テーブルの構造は次のとおりです。

id INT(10)
starting_at DATETIME
ending_at DATETIME
course_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP

users_lecturesテーブルは、ユーザーと講義の関係テーブルです。講義をユーザーにリンクします。そのテーブル構造は次のとおりです。

user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY

attendsテーブルには、出席ユーザーのユーザーID、講義ID、およびcreated_atとupdated_atのタイムスタンプに関する情報が保持されます。そのテーブル構造は次のとおりです。

user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP

質問:

1つのクエリで、ユーザーがまだ参加していない今後の講義のみを選択することは可能ですか?

これが私が試したものですが、行が返されません:

// PHP
$stmt = $pdo->prepare("
SELECT
courses.name AS course,
lectures.id AS id,
lectures.starting_at,
lectures.ending_at,
users.name AS user_name,
users_lectures.user_id
FROM lectures
LEFT JOIN users_courses ON users_courses.course_id = lectures.course_id
LEFT JOIN courses ON courses.id = users_courses.course_id
LEFT JOIN users_lectures ON users_lectures.lecture_id = lectures.id
LEFT JOIN users ON users.id = users_lectures.user_id
LEFT JOIN attends ON attends.lecture_id = users_lectures.lecture_id
WHERE users_lectures.user_id = :user_id
AND lectures.ending_at > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 1 MINUTE)
AND lectures.ending_at > DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 1 MINUTE)
AND attends.lecture_id != users_lectures.lecture_id
AND attends.user_id != :user_id
ORDER BY lectures.starting_at DESC");

何かが足りないのでしょうか、それとも構造全体を間違った方法で考えているのでしょうか。

長いテキストを提供して申し訳ありませんが、できるだけ具体的にしたいと思いました。どんな助けでも大歓迎です:)

Spasticmonkey

まず第一に、あなたはあなたが返したいものの主題から始める必要があります。それはユーザーになります。したがって、これが最初に選択するテーブルになります(ここで注意:簡潔にするためにASを使用してテーブルの名前を変更してください):

Select *
From users AS u

次に、必要なデータをリンクします。どれだけ具体的にしたいかによって、必要な結合の数によって異なります(たとえば、courseIDとCourseName)。

ここで、名前などの人間が読める形式のデータがたくさん必要だと仮定して、次の表をリンクします。

LEFT OUTER JOIN users_lectures AS ul ON u.id = ul.userid
LEFT OUTER JOIN lectures AS l ON l.id = ul.lectureid
LEFT OUTER JOIN courses AS c ON c.id = l.courseid
LEFT OUTER JOIN attends AS a ON a.userid = u.id AND a.lectureid = l.id

さらに、出席しなかった人を見つけるために、出席テーブルには含まれないため、出席の値がnullである人をチェックするだけです。

WHERE a.userid IS NULL

ちなみに、WHERE句でこれを使用しても結果は得られません。

AND attends.lecture_id != users_lectures.lecture_id

あなたはこの声明に参加しているので

LEFT JOIN attends ON attends.lecture_id = users_lectures.lecture_id

互いに矛盾する

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ