MySQL 中的分层查询
Hierarchical query in MySQL
具有 table 结构和数据:
| ID | PARENT | FIELD_1 | FIELD_2 | RATING |
+------------------------------------------+
| 1 | NULL | F1V1 | F2V1 | 10 |
| 2 | 1 | F1V2 | F2V2 | 20 |
| 3 | 2 | F1V3 | F2V3 | 30 |
| 4 | 3 | F1V4 | F2V4 | 40 |
有没有办法得到这样的结果:
| ID | F_1 | F_2 | P_F_1 | P_F_2 | G_F_1 | G_F_2 | S_R |
+-------------------------------------------------------------+
| 1 | F1V1 | F2V1 | NULL | NULL | NULL | NULL | 10 |
| 2 | F1V2 | F2V2 | F1V1 | F2V1 | NULL | NULL | 30 |
| 3 | F1V3 | F2V3 | F1V2 | F2V2 | F1V1 | F2V1 | 60 |
| 4 | F1V4 | F2V4 | F1V3 | F2V3 | F1V2 | F2V2 | 90 |
如你所见,我真正想要的是对于每条记录,如果有 parent (P)、grandparent (G) 等记录(递归可能为 4 levels 或任何其他已知的有限数字),它们祖先的字段加上前缀(可以在查询之外以编程方式发生)和递归计算值的 SUM(或任何其他 GROUP 函数)。
前记录 #4:
ID = 4
FIELD_1 AS F_1 = F1V4
FIELD_2 AS F_2 = F2V4
PARENT_FIELD_1 AS P_F_1 = F1V3
...
GRANDPARENT_FIELD_2 AS G_F_2 = F2V2
SUM_RATING AS S_M = (40 + 30 + 20) = 90**
注意:
即使记录 #1 是记录 #4 (grand-grandparent) 的祖先,它的评级也不会计算在总和中,因为它不包含在查询中。
最简单的方法:
SELECT t.id,
t.field_1 f_1,
t.field_2 f_2,
p.field_1 p_f_1,
p.field_2 p_f_2,
g.field_1 g_f_1,
g.field_2 g_f_2,
t.rating + COALESCE(p.rating,0) + COALESCE(g.rating,0) s_r
FROM table_name t
LEFT JOIN table_name p
ON p.id = t.parent
LEFT JOIN table_name g
ON g.id = p.parent
并将左连接、添加和字段选择添加到已知的递归级别。
具有 table 结构和数据:
| ID | PARENT | FIELD_1 | FIELD_2 | RATING |
+------------------------------------------+
| 1 | NULL | F1V1 | F2V1 | 10 |
| 2 | 1 | F1V2 | F2V2 | 20 |
| 3 | 2 | F1V3 | F2V3 | 30 |
| 4 | 3 | F1V4 | F2V4 | 40 |
有没有办法得到这样的结果:
| ID | F_1 | F_2 | P_F_1 | P_F_2 | G_F_1 | G_F_2 | S_R |
+-------------------------------------------------------------+
| 1 | F1V1 | F2V1 | NULL | NULL | NULL | NULL | 10 |
| 2 | F1V2 | F2V2 | F1V1 | F2V1 | NULL | NULL | 30 |
| 3 | F1V3 | F2V3 | F1V2 | F2V2 | F1V1 | F2V1 | 60 |
| 4 | F1V4 | F2V4 | F1V3 | F2V3 | F1V2 | F2V2 | 90 |
如你所见,我真正想要的是对于每条记录,如果有 parent (P)、grandparent (G) 等记录(递归可能为 4 levels 或任何其他已知的有限数字),它们祖先的字段加上前缀(可以在查询之外以编程方式发生)和递归计算值的 SUM(或任何其他 GROUP 函数)。
前记录 #4:
ID = 4
FIELD_1 AS F_1 = F1V4
FIELD_2 AS F_2 = F2V4
PARENT_FIELD_1 AS P_F_1 = F1V3
...
GRANDPARENT_FIELD_2 AS G_F_2 = F2V2
SUM_RATING AS S_M = (40 + 30 + 20) = 90**
注意: 即使记录 #1 是记录 #4 (grand-grandparent) 的祖先,它的评级也不会计算在总和中,因为它不包含在查询中。
最简单的方法:
SELECT t.id,
t.field_1 f_1,
t.field_2 f_2,
p.field_1 p_f_1,
p.field_2 p_f_2,
g.field_1 g_f_1,
g.field_2 g_f_2,
t.rating + COALESCE(p.rating,0) + COALESCE(g.rating,0) s_r
FROM table_name t
LEFT JOIN table_name p
ON p.id = t.parent
LEFT JOIN table_name g
ON g.id = p.parent
并将左连接、添加和字段选择添加到已知的递归级别。