2016-05-16 169 views
2

我有以下表格:如何在MySQL中編寫此查詢?

project(pid integer primary key, title varchar(30), finished boolean) 
action(aid integer primary key, title varchar(30), finished boolean) 
project_action(pid integer, aid integer, primary key(pid, aid)) 

一個項目可以包含多個動作和動作只能屬於無或一個項目。因此,cardinatlity是(項目)0..1 < - > *(action)。

我怎樣才能得到剛完成的項目?

我想這一點,但是這已經給了我,如果只是它的一個動作被完成了一個項目:

SELECT pid FROM project WHERE pid IN (SELECT DISTINCT pid FROM project_action WHERE aid IN (SELECT aid FROM action WHERE action.finished = true)); 

回答

1

雖然有些不清楚餐桌內容的意圖,我想你的結構可能是有點過。讓我舉一個汽車修理的簡單例子(而且我絕不是汽車修理人員)。

Project, Repair Person "A" car. 
Pre-clean 
Pull dent/repair parts 
Apply any filler 
Sand it 
Paint 

如果「行動」將在多個項目中保持一致,那麼該表將不會有「已完成」布爾標誌。該標誌將特定於正在進行的一個項目。如果我有10輛汽車,我可以完全完成3輛,在不同階段的某處可以有7輛。所以,這麼說,我本來期望更像

project(pid integer primary key, title varchar(30), finished boolean) 
action(aid integer title varchar(30)) 
project_action(pid integer, aid integer, finished boolean, primary key(pid, aid)) 

的結構說了這麼多,和你原來的結構後,您還可以有每例如,2,3或多個動作的一個項目,需要對其執行。如果任何行動不完整,那麼整個項目就不完整。我也基於對你的「行動」表的索引(PID,援助,已完成)

然後做一個NOT EXISTS完成=假

SELECT 
     p.pid, 
     p.title 
    from 
     project p 
    where 
     NOT EXISTS (select pa.pid 
        from project_action pa 
         join action a on pa.aid = a.aid 
         AND a.finished = false 
        where pa.pid = p.pid) 

這基本上說明,給我所有沒有「FALSE」項目的項目完成了針對當前項目的任何項目。如果找到符合條件的記錄,EXISTS(或NOT EXISTS)會立即停止。因此,如果某項目有10件事情未完成,只要找到一件事,它就會在符合條件的WHERE中完成,並接受或拒絕項目記錄並轉到下一個項目。

+0

耶謝謝!我忘記了以這種方式使用「NOT EXISTS」,因爲我在兩年內不需要它。 – LPrc

0

我會加入表:

SELECT project.pid FROM project, project_action, action 
WHERE project.pid = project_action.pid 
AND project_action.aid = action.aid 
AND action.finished = TRUE 
+0

儘管第一次嘗試,第二次嘗試,學習正確的JOIN語法與老逗號分開的兩件事情會更好地長期運行。其次,如果一個項目有10個動作,只有6個完成,那麼整個項目就沒有完成。 – DRapp

0

儘量選擇只項目沒有未完成的行動。你應該記住,這種方法會給你沒有行動的項目。

SELECT pid FROM project WHERE pid NOT IN 
    (SELECT DISTINCT pid FROM project_action WHERE aid IN 
    (SELECT aid FROM action WHERE action.finished = false) 
); 
0

試試這個 -

SELECT project.pid FROM project LEFT JOIN project_action ON project_action.pid = project.pid LEFT JOIN action ON project_action.aid = action.aid WHERE action.finished = true

0
SELECT p.pid FROM project p WHERE p.pid NOT IN 
    (SELECT pa.pid FROM project_action pa 
    JOIN action a ON pa.aid = a.aid 
    WHERE a.finished = FALSE)