我有三个表,一个问题,一个预防措施,以及它们之间的链接之一(problem_pa)。问题可能与多种行为有关,也可能与多种问题采取预防措施,即“多对多”关系。 我想要一个SQL语句,它允许我列出仍然处于“开放”状态的所有问题,这些问题在“打开”状态下没有任何预防措施,即所有操作都已执行和关闭。 我找到了与封闭行动相关的未解决问题(见下文):
SELECT p.id, p.slogan, p.state, pa.id, pa.slogan, pa.state
FROM problems p
JOIN problem_pa pp
ON p.id = pp.problem
JOIN preventative_actions pa
ON pa.id = pp.preventative_action
WHERE p.state = "Open" AND pa.state = "Closed"
但是这只能让我成为一部分,因为多对多关系意味着这些问题可能仍然会有与之相关的开放行为。 如何获得没有剩余未处理操作的打开问题列表(仅关闭操作)?
三张桌子:
行的问题(加上与问题无关的其他行):
id (int(11), AUTO_INCREMENT)
slogan (varchar(255))
state (enum ('Open', 'Closed')
带行的preventative_actions(加上其他不相关的行):
id (int(11), AUTO_INCREMENT)
slogan (varchar(255))
state (enum ('Open', 'Closed')
带有行的problem_pa:
problem (int(11), to hold the id from the problems table)
preventative_action (int(11), to hold the id from the actions table)
问题中的示例数据:
1, Problem number 1, Open
2, Problem number 2, Open
3, Problem number 3, Closed
preventative_actions中的示例数据:
1, Action number 1, Open
2, Action number 2, Closed
3, Action number 3, Closed
problem_pa中的示例数据
1, 1
1, 2
2, 1
3, 2
3, 3
我希望我的搜索返回的是问题ID 3 - 这是唯一一个只有关闭操作链接的问题。但是搜索与闭合动作相关的问题将返回问题ID 1和3.我想我真正想要的是(与开放动作相关的问题)的反转,这将给出上面(ids 1和2)的反转。示例
我在数据库中连接了多达60个操作时遇到问题,其中55个现在已关闭,5个仍处于打开状态。以上是简化,但我认为它包含所有相关数据。
答案 0 :(得分:2)
此查询返回状态为“打开”且未打开的preventative_actions 和至少一个已关闭的preventative_actions 的所有问题。
SELECT p.*
FROM problems p
INNER JOIN problem_pa pp ON pp.problem_id = p.id
INNER JOIN preventative_actions pa ON pa.id = pp.preventative_action_id
WHERE p.state = 'Open'
GROUP BY p.id
HAVING SUM(IF(pa.state = 'Open', 1, 0)) = 0 AND SUM(IF(pa.state = 'Closed', 1, 0)) > 0;