1

3つのテーブルを続けてプライマリテーブルに結合するMySQLクエリを作成しようとしていますが、これは、結合される最後のテーブルの値に基づいて条件付きで実行されます。私がやろうとしている2つの方法には、どちらも問題があります。

  • 必要なすべてのプライマリ行が表示されていないか
  • または、そこに無関係な行がいくつかあります。

テーブル構造は既存のシステムの一部であり、変更することはできません。また、SQLを理解したら、これをクエリシステムと統合する方法を見つける必要があるため、SQLは単純であるほど優れています。

ここに多くの詳細を載せます。申し訳ありませんが、これは非常に長い投稿ですが、すべての情報を含める方がよいと思いました。

詳細は次のとおりです。

データ・モデル:

ユーザー、コース、およびcuiと呼ばれる特定のコースの各ユーザーのユーザー情報を格納する中間コンテンツタイプがあります。すべてのユーザーのリストを確認する必要があります。そのユーザーとコースのcuiがある場合は、それも含める必要があります。

データベースでは、cuiのフィールドの内容は別々のテーブルに格納され、問題の一部であるcui_idを介して結合されます。

簡素化されたデータベース構造:

  • プライマリテーブル:ユーザー(フィールド:uid、名前)
  • Cuiテーブル:ノード(フィールド:cui_id)
  • ユーザーフィールドテーブル(フィールド:cui_id、uid)
  • コースフィールドテーブル(フィールド:cui_id、course_id)

参加する

user     user_field         node         course_field
----     ----------         -------      ------------
uid ==== uid          
name     cui_id =========== cui_id ===== cui_id
                                         course_id    = 202

試行されたクエリ:

次のクエリは、次のユーザーを使用して小さなサンプルデータセットで実行されます。

  • ユーザー2:照会されたコースのキューがあり、他のコースのキューがあります。
  • ユーザー1:他のコースの手がかりはありますが、質問されたコースの手がかりはありません。
  • ユーザー6:手がかりがありません。

この最初のクエリは最後のテーブルの条件付き結合です。問題は、正しいcuiではないユーザー2の余分な行が含まれていることです。必ずしも正しい行が表示されるとは限らないと思ったので、GROUPBYを使用したくありませんでした。

SELECT user.uid, user.name, field_user.cui_id,
field_course.course_id
FROM user
LEFT JOIN field_user
ON
user.uid = field_user.uid
LEFT JOIN node AS cui
ON
cui.id = field_user.cui_id
LEFT JOIN field_course
ON
field_course.cui_id = cui.id
AND
field_course.course_id = 202

結果:

uid     name        cui_id  course_id
---------------------------------------------
4       User One    772     NULL
5       User Two    434     202
5       User Two    771     NULL
35      User Six    NULL    NULL

代替案はこれです:

SELECT user.uid, user.name, field_user.cui_id,
field_course.course_id
FROM user
LEFT JOIN field_user
ON
user.uid = field_user.uid
LEFT JOIN node AS cui
ON
cui.id = field_user.cui_id
LEFT JOIN field_course
ON
field_course.cui_id = cui.id
WHERE (
field_course.course_id = 202 OR ISNULL(field_course.course_id))

結果:

uid     name    cui_nid     course_nid
---------------------------------------------
5       User Two    434     202
35      User Six    NULL    NULL

その問題は、ユーザー1が他の手がかりを持っているため、ユーザー1が除外されていることです。これは、正しいコースではありません。

だから問題は、どうやってこれを手に入れるのかということです。

uid     name        cui_id  course_id
--------------------------------------------
4       User One    772     NULL
5       User Two    434     202
35      User Six    NULL    NULL
4

1 に答える 1

1

本当にそれほどきれいではありませんが、トリックを行う必要があります:

-- Select to get all users irrespective of whether they have a row in field_course or field_user
SELECT user.uid, user.name, field_user.cui_id,
null as course_id
FROM user
LEFT JOIN field_user ON user.uid = field_user.uid
LEFT JOIN node AS cui ON cui.id = field_user.cui_id 
where user.uid not in
(
-- Inline view to get only users that have both a field_course & field_user row
SELECT user.uid
FROM user
INNER JOIN field_user ON user.uid = field_user.uid
INNER JOIN node AS cui ON cui.id = field_user.cui_id
INNER JOIN field_course ON field_course.cui_id = cui.id
where field_course.course_id = 202
)
union all
-- Select to get only users that have both a field_course & field_user row
SELECT user.uid, user.name, field_user.cui_id,
field_course.course_id
FROM user
INNER JOIN field_user ON user.uid = field_user.uid
INNER JOIN node AS cui ON cui.id = field_user.cui_id
INNER JOIN field_course ON field_course.cui_id = cui.id
where field_course.course_id = 202;

編集

テストに使用したテーブル構造とデータは次のとおりです。

CREATE TABLE `user` (
  `uid` int(10) unsigned NOT NULL,
  `name` varchar(20) NOT NULL
);

CREATE TABLE `node` (
`id` int(10) unsigned not null primary key
);

CREATE TABLE `field_user` (
  `uid` int(10) unsigned NOT NULL,
  `cui_id` int(10) unsigned NOT NULL
);

CREATE TABLE `field_course` (
  `uid` int(10) unsigned NOT NULL,
  `cui_id` int(10) unsigned NOT NULL,
`course_id` int(10) unsigned NOT NULL
);

insert into user (uid,name) values (4,"User One");
insert into user (uid,name) values (5,"User Two");
insert into user (uid,name) values (35,"User Six");

insert into node (id) values (771);
insert into node (id) values (772);
insert into node (id) values (434);

insert into field_user (uid,cui_id) values (4,772);
insert into field_user (uid,cui_id) values (5,434);
insert into field_user (uid,cui_id) values (5,771);

insert into field_course (uid,cui_id,course_id) values (5,434,202);
于 2012-05-02T12:58:09.057 に答える