2014-04-02 46 views
0

我想根據已選擇的行中的值從數據庫中的連接表中選擇行。基本上,如果父級或Granparent行處於活動狀態,則還應在結果中包含子級或孫級行。MySQL:根據已選行中的值選擇行

我試圖使用JOINSUNIONS的不同組合來獲得我想要的結果而沒有成功。

這是我的數據。例如:

表1:目標 (目標可供成員設置爲目標或完成)

id | name  | parent 
--------------------------- 
A | Obj A | null 
A1 | Obj A1 | A 
A2 | Obj A2 | A 
A2-1 | Obj A2.1 | A2 
B | Obj B | null 
B1 | Obj B1 | B 
B1-1 | Obj B1.1 | B1 
C | Obj C | null 
C1 | Obj C1 | C 
C1-1 | Obj C1.1 | C1 

表2:memberObjectives (目標成員已經完成或設定爲目標)

id | objective | member | status 
----------------------------------- 
1 | A   | 001 | goal 
2 | A1  | 001 | complete 
3 | C   | 001 | goal 

期望的結果:加入兩個表,並選擇所有行的狀態是goalcomplete或當父母或祖父母物鏡具有goalcomplete狀態。

objective | member | name  | status 
------------------------------------------ 
A   | 001 | Obj A | goal 
A1  | 001 | Obj A1 | complete 
A2  | 001 | Obj A2 | null 
A2-1  | 001 | Obj A2-1 | null 
C   | 001 | Obj C | goal 
C1  | 001 | Obj C1 | null 
C1-1  | 001 | Obj C1.1 | null 

A2C2都包括在內,因爲他們的父母ACgoalA2-1C1-1一個狀態都包括在內,因爲他們有與goal狀態祖父母。 B及其子女和granchild目標不包括在內,因爲memberObjectives表中的B的狀態爲completegoal

我的最新嘗試,我知道甚至沒有接近如下:

SELECT DISTINCT mo.objective, mo.member, o.name, mo.status 
    FROM objectives AS o 
    LEFT JOIN (SELECT * FROM memberObjectives 
    WHERE member = '001') AS mo ON o.id = mo.objective 
    LEFT JOIN objectives AS o2 ON o2.id = o.parent 
    LEFT JOIN objectives AS o3 ON o3.id = o2.parent 
    GROUP BY o.id 

謝謝您可以提供任何幫助!

+0

如果你的ID是數字而不是A,A1等,這將是容易的。是你唯一想要的A嗎?或者僅僅是你的榜樣?因爲你可以過濾掉A.問題是祖父母不可能只是加入 –

+0

@JohnRuddell'A's就是這個例子。我可能想要得到所有具有「目標」或「完成」狀態或者具有該狀態的父母或祖父母的「A」和「C」,但沒有任何「B」,因爲該成員沒有完成任何「B」或將其設定爲目標。 –

+0

我現在想知道是否有一種方法來連接表,所以我最終得到了兩個額外的列'parentStatus'和'grandparentStatus',這樣如果這些列或原始狀態列中的任何一個都是'goal'或'complete'包含在結果中。 ('WHERE status ='goal'OR status ='complete'OR parentStatus ='goal'OR parentStatus ='complete'OR grandparentStatus ='goal'OR grandparentStatus ='complete'') –

回答

0

不能測試,但試試這個:

SELECT mo.objective, mo.member, o.name, mo.status 
    FROM objectives AS o 
    LEFT JOIN memberObjectives o.id=mo.objetive 
WHERE status='goal' or status='complete' 
OR o.id IN(select parent from objetives o inner join memberObjectives mo on o.parent=mo.objetive WHERE status='goal' or status='complete') 

這應該給你的狀態目標或完整和衛生組織父記錄有該記錄。我想你延伸到格蘭父親。希望能幫助到你。

+0

謝謝!它不喜歡第二次被稱爲「目標AS」的事實。我修正了一些錯別字,並給第二個電話打了個'別名'。現在它說'#1054 - 'on clause'中的未知列'mo.objective'。這裏是當前查詢:'SELECT mo.objective,mo.member,o.name,mo.status FROM goals AS o LEFT JOIN memberObjectives AS mo ON o.id = mo.objetive WHERE status ='goal'or status ='完成' OR o.id IN(從目標選擇父項o2內部連接成員o2.parent上的目標mo2 = mo.objective WHERE status ='goal'或status ='complete')' –

+0

這隻返回兩個有GOAL和COMPLETE ..它不添加孩子和孫子。 –

0

三問你看:看FIDDLE的工作示例

,如果你可以通過ID作爲一個過濾器,然後該查詢將不正是你想要的。

SELECT t.id as objective, mo.member, t.name, mo.status from(
    SELECT * FROM objective o 
)AS t 
LEFT JOIN memberObjective mo ON mo.objective = t.id 
WHERE t.id in(SELECT objective FROM memberObjective) 
OR t.parent in(SELECT o.id FROM objective o where o.id like "%A%") 

此查詢獲取父級,但不是祖父母。

SELECT t.id as objective, mo.member, t.name, mo.status from(
    SELECT * FROM objective o 
)AS t 
LEFT JOIN memberObjective mo ON mo.objective = t.id 
WHERE t.id in(SELECT objective FROM memberObjective) 
OR t.parent in(SELECT o.id FROM objective o join memberObjective mo on mo.objective = o.id) 

此查詢得到父母和祖父母,但它並沒有過濾掉B的..還有就是在數據庫中沒有足夠的數據去添加祖父母,因爲A2僅出現兩次,你的表及其父母和身份證。

SELECT t.id as objective, mo.member, t.name, mo.status from(
    SELECT * FROM objective o 
)AS t 
LEFT JOIN memberObjective mo ON mo.objective = t.id 
WHERE t.id in(SELECT objective FROM memberObjective) 
OR t.parent in(SELECT o.id FROM objective o left join memberObjective mo on mo.objective = o.id) 
---- you could add LIMIT 4 to get the correct results but thats another semi hacky way to do it 
+0

感謝您的回答。我們正在接近,我正在學習一些新的東西。看着FIDDLE,唯一能夠得到理想結果的查詢是第一個,但那是因爲它正在尋找'A's。該解決方案需要基於「狀態」等於「目標」或「完成」來爲自己,其父母或其祖父母。我用'C'目標更新了這個問題,以便更好地展示理想的結果。至今再次感謝您的幫助! –

0

我創建了一個似乎現在工作的解決方案。它增加了幾個連接,將parentStatusgrandparentStatus列包括到每一行中。現在如果status,parentStatusgrandparentStatusgoalcomplete該行包含在結果中。

的MySQL查詢的結果如下情況如下:

objective | member | name  | status | parentStatus | grandparentStatus 
------------------------------------------------------------------------------ 
A   | 001 | Obj A | goal  | null   | null 
A1  | 001 | Obj A1 | complete | goal   | null 
A2  | 001 | Obj A2 | null  | goal   | null 
A2-1  | 001 | Obj A2-1 | null  | null   | goal 
C   | 001 | Obj C | goal  | null   | null 
C1  | 001 | Obj C1 | null  | goal   | null 
C1-1  | 001 | Obj C1.1 | null  | null   | goal 

下面是MySQL查詢:

SELECT DISTINCT * FROM objectives AS o 
    LEFT JOIN (SELECT * FROM memberObjectives WHERE member = '001') 
    AS mo ON mo.objective = o.id 
    LEFT JOIN (SELECT mo2.status AS parentStatus, mo2.objective AS parentObjective 
    FROM memberObjectives AS mo2 
    LEFT JOIN objectives AS o2 ON o2.parent = mo2.objective 
    WHERE mo2.member = '001') 
     AS parent ON parent.parentObjective = o.parent 
    LEFT JOIN (SELECT mo3.status AS grandparentStatus, mo3.objective AS grandparentObjective 
    FROM memberObjectives AS mo3 
    LEFT JOIN objectives AS o3 ON o3.parent = mo3.objective 
    WHERE mo3.member = '001') 
     AS grandparent ON grandparent.grandparentObjective = o.parent 
    WHERE mo.status = 'goal' OR mo.status = 'complete' 
    OR parentStatus = 'goal' OR parentStatus = 'complete' 
    OR grandparentStatus = 'goal' OR grandparentStatus = 'complete' 
    GROUP BY o.id 

根據我原來的問題的解決方案是不是根據已經選擇的行中的值選擇一行,而是將表連接到具有額外列以檢查來自其他行的必要值的表。

+0

該解決方案正在運行,但我願意接受更優雅的解決方案作爲答案。 –