如何在MySQL中编写此查询?

问题描述:

我有以下表格:如何在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)); 

虽然有些不清楚餐桌内容的意图,我想你的结构可能是有点过。让我举一个汽车修理的简单例子(而且我绝不是汽车修理人员)。

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

我会加入表:

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

尽量选择只项目没有未完成的行动。你应该记住,这种方法会给你没有行动的项目。

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

试试这个 -

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

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)