2017-07-25 17 views
1

私は、ユーザ、コース、およびユーザがコースのステータスを持つオンライン大学に取り組んでいます。私はユーザーのリストとコースの別のリストを持っています。私は、ユーザーがまだ開始していないコースのヌルステータスを含む、指定されたすべてのユーザーおよびコースのコースステータスを見つけたいと思います。ですから、例えば関係が存在しなくても、3つのテーブル間の関係を検索するためのMySQLクエリ

User IDs: [1, 7, 14, 21] 
Course IDs: [5, 8, 36, 50] 

望ましい結果:

Name  Course      Status 
John Doe How to Tie your Shoes  Complete 
John Doe How to Paint your House In Progress 
Jane Doe How to Tie your Shoes  Complete 
Jane Doe How to Paint your House Not Started <-- These are the tricky ones 
...

私がテーブルの上にLEFT JOINを実行し、いくつかのNULL値を得ることができるようです

、私は 'Not Started'に合体することができますが、私が探しているコースやユーザを制限するためにいくつかの制約を加えるとすぐに... NULLのコースIDが明確にないので、 m上記のコースリスト。

ここでは例のクエリはあなたに私が(他のものの間で)しようとしてきたかのアイデアを与えることです:

SELECT 
    `users`.`name` AS `Name`, 
    `users`.`email` AS `Email`, 
    `courses`.`number` AS `Course #`, 
    `courses`.`name` AS `Course`, 
    COALESCE(`courses_users_statuses`.`name`, 'Not Started') AS `Status` 
FROM 
    `users` 
    LEFT JOIN `courses_users` 
     ON `courses_users`.`user_id` = `users`.`id` 
    LEFT JOIN `courses` 
     ON `courses`.`id` = `courses_users`.`course_id` 
    LEFT JOIN `courses_users_statuses` 
     ON `courses_users_statuses`.`id` = `courses_users`.`status_id` 
WHERE 
    `courses`.`id` IN ([1, 2, 3, 4, 5, 10, 11, 12, 16, ...]) 
    AND `users`.`id` IN ([1, 2, 3, 4, 5, 20, 21, 36, 48, ...]) 
ORDER BY 
    `users`.`name`, 
    `courses`.`number` 

このような何かを書く方法上の任意のアイデアは?また、詳細やコード/テーブルの例をさらに提供できるかどうかを教えてください。

編集:ここでは以下の回答からのアドバイスを使用して、私の更新クエリです:

SELECT 
    `users`.`name` AS `Name`, 
    `users`.`email` AS `Email`, 
    `courses`.`number` AS `Course #`, 
    `courses`.`name` AS `Course`, 
    COALESCE(`courses_users_statuses`.`name`, 'Not Started') AS `Status` 
FROM 
    `users` 
     LEFT JOIN 
    `courses_users` ON `courses_users`.`user_id` = `users`.`id` 
     LEFT JOIN 
    `courses` ON `courses`.`id` = `courses_users`.`course_id` AND `courses`.`id` IN (1, 2, 3, 4, 5) 
     LEFT JOIN 
    `courses_users_statuses` ON `courses_users_statuses`.`id` = `courses_users`.`status_id` 
WHERE 
    `users`.`id` IN (1, 2, 3, 4, 5) 
ORDER BY 
    `partners`.`name`, 
    `users`.`name`, 
    `courses`.`number` 

この更新された例では、改善されているが、今では何のコース名または番号が存在しないレコードを示していますが、ステータスがあります。私はそれがどのように存在するべきコース関係の地位をつかんでいるのか分かりません。代わりにそれらはNULL(または "Not Started")でなければなりません。

`users`テーブル:

id name    email 
1  Stevie McComb [email protected] 
2  John Doe   [email protected] 
3  Jane Doe   [email protected] 

`courses`テーブル:

id number name 
1  101  Navigation 
2  102  Logging In 
3  103  Updating Records 
4  104  Managing Users 

`courses_users`テーブル:

course_id user_id status_id completed_at 
1   1   2   2017-01-01 00:00:00 
3   1   1   2017-01-05 00:23:00 
1   2   2   2017-04-13 15:00:37 

`courses_users_statuses`テーブル:

ここでは、データベースからいくつかのサンプルデータをです
id name   slug 
1  In Progress progress 
2  Complete  complete 

望ましい結果:

Name    Email    Course # Course    Status 
Stevie McComb [email protected] 101   Navigation   Complete 
Stevie McComb [email protected] 102   Logging In   Not Started 
Stevie McComb [email protected] 103   Updating Records In Progress 
Stevie McComb [email protected] 104   Managing Users  Not Started 
John Doe   [email protected] 101   Navigation   Complete 
John Doe   [email protected] 102   Logging In   Not Started 
John Doe   [email protected] 103   Updating Records Not Started 
John Doe   [email protected] 104   Managing Users  Not Started 
Jane Doe   [email protected] 101   Navigation   Not Started 
Jane Doe   [email protected] 102   Logging In   Not Started 
Jane Doe   [email protected] 103   Updating Records Not Started 
Jane Doe   [email protected] 104   Managing Users  Not Started 

現在の結果は:

Name    Email    Course # Course    Status 
Stevie McComb [email protected]         Complete 
Stevie McComb [email protected]         Not Started 
Stevie McComb [email protected] 103   Updating Records In Progress 
Stevie McComb [email protected]         Not Started 
John Doe   [email protected] 101   Navigation   Complete 
John Doe   [email protected]         Not Started 
John Doe   [email protected]         Not Started 
John Doe   [email protected]         Not Started 
Jane Doe   [email protected]         Not Started 
Jane Doe   [email protected]         Not Started 
Jane Doe   [email protected]         Not Started 
Jane Doe   [email protected]         Not Started 

答えて

0

問題はnull値を許すことなく、あなたのwhere句に制約を入れているということです。これ基本的にleft joininner joinに戻します。

この問題を解決するには、明示的にNULLを許可するか、ロジックをjoin句(自分の設定)に移動できます。

select 
    `users`.`name` as `name`, 
    `users`.`email` as `email`, 
    `courses`.`number` as `course #`, 
    `courses`.`name` as `course`, 
    coalesce(`courses_users_statuses`.`name`, 'not started') as `status` 
from 
    `users` 
    left join `courses_users` 
     on `courses_users`.`user_id` = `users`.`id` 
    left join `courses` 
     on `courses`.`id` = `courses_users`.`course_id` 
     and `courses`.`id` in ([1, 2, 3, 4, 5, 10, 11, 12, 16, ...]) 
    left join `courses_users_statuses` 
     on `courses_users_statuses`.`id` = `courses_users`.`status_id` 
where 
    `users`.`id` in ([1, 2, 3, 4, 5, 20, 21, 36, 48, ...]) 
order by 
    `users`.`name`, 
    `courses`.`number` 
+0

私は完全に拘束を追加することを忘れていましたジョインにそれだけで問題を解決するかもしれません。今日私はこのプロジェクトをもう一度やり直して、他の問題に遭遇したらどうなるか教えてください。 –

+0

@StevieMcComb:これがあなたの質問に答えた場合は、適切な回答をアップ/アップすることを検討してください。私はあなたが新しく、知りません(https://stackoverflow.com/help/someone-answers)ので、これについて言及します。 – Jacobm001

+0

遅れて申し訳ありませんが、今朝までこのプロジェクトをやり直すチャンスはありませんでした。これは、それが以前ではなかった地域でヌル値を返すように私を近づけました...しかし、それは私に新たな頭痛を引き起こしています。コース名や番号がランダムに欠けているレコードが返されます。コースのステータスが「完了」または「進行中」の場合、これはヌル値がないことを意味しますが、何らかの理由でコースの詳細が表示されない場合もあります。例: 名前=> 'John Doe'、 コース番号=>、 コース名=> ステータス=> '完了' –

0

私は潜在的にNULL値を使用して対処しなければならないときに、私は...インスタンス

SELECT 
IFNULL(Course, 'Nothing Found') AS course 
FROM 
Course 
Where.... 

それとも、あなたのWHERE句で指定することができますについて

IFNULL(field_name, 'use this value instead'); 

使用

WHERE Course IS NOT NULL 
関連する問題