2012-05-02 55 views
1

我想寫一個MySQL查詢,連接到主表的一行中的三個表,但這是否有條件地基於最後一個表中的值被連接。這兩種方式我想這樣做有兩個問題:有條件的連接基於進一步行下表

  • 要麼不是所有的主行我需要的是顯示
  • 或者我在那裏得到一些額外的無關行。

表結構是現有系統的一部分,我無法更改它。另外,一旦我找出SQL,我將不得不尋找一種將其與查詢系統集成的方式,因此SQL越簡單越好!

我打算把很多細節放在這裏,對不起,這是一個很長的帖子,但我認爲最好包括所有的信息。

下面是詳細信息:

數據模型:

有用戶,課程和存儲對某一課程的每個用戶,被稱爲崔永元用戶信息的媒介內容類型。 我需要查看所有用戶的列表,並且如果有該用戶和課程的cui,也包括它。

在數據庫中,cui的字段內容存儲在單獨的表中,並通過cui_id加入,這是故障的一部分。

剝離下來的數據庫結構:

  • 主表:用戶(字段:UID,名稱)
  • 崔表:節點(字段: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 

嘗試查詢:

  • 用戶二:

    下面的查詢與以下用戶設置一個小樣本數據運行已爲課程一崔永元質疑,並有其他課程 cuis。

  • 用戶一:爲其他課程提供了cuis,但不是針對其中一個查詢的 。
  • 用戶六:沒有cuis。

這第一個查詢是最後一個表的條件連接,問題是它包含了一個額外的用戶二行,它不是正確的cui。 我不想GROUP BY,因爲我認爲它不一定會給我正確的行。

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 

麻煩與一個被它忽略了用戶之一,因爲用戶一有其他cuis,只是不適用正確的路線。

所以問題是,我怎麼得到這個?

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

爲什麼你需要節點表嗎?另外,你能否把你的測試數據也放進去? –

+0

把你的數據庫表的整個結構 –

+0

你所說的關於你想要執行的查詢是「*我需要看到所有用戶的列表,如果有一個用戶和課程的cui,包括它太*「 - 當你說」那個用戶和課程「時,你指的是哪個課程? – eggyal

回答

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); 
+0

嗯,謝謝是的,它確實有效,不確定我能否將它作爲我正在使用的查詢系統的一部分來實現,但我會放棄它。 爲了他人的利益,我將這種方法解釋爲: 1)選擇所有沒有cui參加所需課程的用戶 2)選擇所有擁有cui的用戶3)創建一個聯盟的兩個結果集。 – seddonym