我想根据已经选择的行中的值从数据库中的连接表中选择行。基本上,如果父级或granparent行处于活动状态,则还会在结果中包含子级或孙级行。
我尝试使用JOINS
和UNIONS
的不同组合来获得我想要的结果但没有成功。
以下是我的示例数据:
表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
期望的结果:加入两个表并选择状态为goal
或complete
的所有行或父级或祖父级目标的状态为{{1}的所有行}或goal
。
complete
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
和A2
包括在内,因为他们的父母C2
和A
的状态为C
和goal
以及{{1}包括在内,因为他们的祖父母的状态为A2-1
。 C1-1
及其子级和格式目标未包括在内,因为goal
表格中没有B
个状态为B
或memberObjectives
。
我最近的尝试,我知道甚至不接近如下:
complete
感谢您提供任何帮助!
答案 0 :(得分: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')
这应该为您提供状态目标或完成的记录以及父母拥有该记录的记录。我是由你来扩展到格兰父亲。希望它有所帮助。
答案 1 :(得分:0)
您可以查看三个查询:请参阅FIDDLE了解工作示例
如果你可以通过id作为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 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在您的表中只出现两次,而它的父和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 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
答案 2 :(得分:0)
我创建了一个似乎现在正在运行的解决方案。它添加了一些连接,以便在每行中包含parentStatus
和grandparentStatus
列。现在,如果status
,parentStatus
或grandparentStatus
为goal
或complete
,则该行将包含在结果中。
以下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
根据我的原始问题,解决方案不是基于已选择的行中的值选择行,而是连接表以使用额外的列来检查来自其他行的必要值。