我有一个包含字段的表:
我想选择id,name,parent name,grandparent name。
我可以通过自我加入来做到这一点吗?我基本上想要检索“name”值,其中parent_id = id并返回一行。
示例:
id name parent_id grandparent_id
-----------------------------------------------
1 Milton NULL NULL
2 Year 3 1 NULL
3 Class A 2 1
所以我想选择第3行(id = 3),但不是只返回parent_id和grandparent_id,我希望查询根据它们的id返回这些记录的名称。我可以创建一个复合字段,比如称为parent_id_name和grandparent_id_name吗?
我很确定我正在做的事情可以通过自我加入或子查询来实现,但到目前为止我尝试过的所有代码都无法正常工作。任何帮助都会非常感激。
答案 0 :(得分:2)
这是您要求的查询:
# By using LEFT JOINs you will be able to read any record,
# even one with missing parent/grand-parent...
SELECT
child.id,
child.name,
parent.id,
parent.name,
gparent.id,
gparent.name
FROM
some_table child
LEFT JOIN some_table parent ON
parent.id = child.parent_id
LEFT JOIN some_table gparent ON
gparent.id = child.grandparent_id
WHERE
child.id = 3
但我还要补充说,拥有一个字段grandparent_id的冗余对我来说听起来不对...
你的桌子应该只是:
id name parent_id
1 Milton NULL
2 Year 3 1
3 Class A 2
请注意,如果我知道1
是2
的父级,我就不需要在记录3
上再次重复相同的信息......
在最后一种情况下,你的选择可能是这样的:
SELECT
child.id,
child.name,
parent.id,
parent.name,
gparent.id,
gparent.name
FROM
some_table child
LEFT JOIN some_table parent ON
parent.id = child.parent_id
LEFT JOIN some_table gparent ON
gparent.id = parent.parent_id -- See the difference?
WHERE
child.id = 3
查询的工作方式相同,您也可以使用更多“规范化”的数据库。
编辑:这是非常基本的东西,但我想这与这个答案有关......
不应使用这种非规范化(即在同一记录上同时具有parent_id
和grandparent_id
),因为它允许数据库不一致。
例如,假设插入了一条新记录:
id name parent_id grandparent_id
1 Milton NULL NULL
2 Year 3 1 NULL
3 Class A 2 1
4 Invalid Rec 2 3
没有任何意义,对吗?记录4
表明3
是其祖父母。因此,3
应该是记录2
的父级。但这不是记录3
本身所述的内容。哪条记录是对的?
您可能认为这是一个奇怪的错误,并且您的数据库永远不会像这样。但我的经验却说不然 - 如果可能发生错误,最终会发生错误。应该避免非规范化,不仅仅是因为某些数据库大师这样说,而是因为它确实增加了不一致性,并使维护更加困难。
当然,非规范化数据库可能更快。但是,根据经验,您应该考虑性能在系统准备好生产后 之后,通过一些自动化或经验测试,存在瓶颈。相信我,我已经看到更糟糕的设计选择被错误的表现预期所证明......
答案 1 :(得分:1)
SELECT t1.name,
MAX(CASE WHEN t2.id = t1.parent_id then t2.name end) as Parent,
MAX(CASE WHEN t2.id = t1.grandparent_id then t2.name end) as GrandParent
FROM your_table t1
LEFT OUTER JOIN your_table t2 ON t2.id IN (t1.parent_id, t1.grandparent_id)
WHERE t1.id = 3
group by t1.id, t1.name
答案 2 :(得分:1)
尝试这样,这是针对单亲
SELECT e.entity_name AS 'entity',
m.entity_name AS 'parent'
FROM table_name AS e
LEFT OUTER JOIN table_name AS m ON e.entity_parent =m.entity_id
或 检查以下链接: