MySQL数据库包含城镇内的国家,城镇和地区,所有这些都在“mailshot”表中。我想以降序粒度,使用和内连接的顺序返回整个集合。我实际上想向用户显示一个下拉列表,供他们选择城镇内的乡村或城镇或区域。
数据如下所示:
mailshot_id mailshot_parent mailshot_name mailshot_level 49 0 England 0 56 0 Scotland 0 140 49 London 1 149 49 York 1 191 56 Glasgow 1 300 140 Wimbledon 2 310 140 Westminster 2 493 56 Edinburgh 1
我希望它输出如下:
mailshot_id mailshot_parent mailshot_name mailshot_level 49 0 England 0 149 49 York 1 140 49 London 1 300 140 Wimbledon 2 310 140 Westminster 2 56 0 Scotland 0 191 56 Glasgow 1 493 56 Edinburgh 1
我几乎得到了这个:
SELECT p.mailshot_id as p_id, p.mailshot_name as p_name, p.mailshot_level as p_level, p.mailshot_parent as p_parent, c.mailshot_id as c_id, c.mailshot_parent as c_parent, c.mailshot_level as c_level, c.mailshot_name as c_name, case WHEN p.mailshot_parent = 0 THEN p.mailshot_id ELSE p.mailshot_parent END AS calcOrder FROM mailshot p LEFT JOIN mailshot c ON p.mailshot_id = c.mailshot_parent ORDER BY calcOrder , p_id "
但是它没有将孙子记录(级别2)分组到子记录(级别1)附近我认为“案例”部分必须是错误的,我需要在mailshot_id和parent_id之间建立一些依赖于级别的关系。但我想不出来。
有什么建议吗?提前谢谢。
答案 0 :(得分:1)
不幸的是,MySQL不支持层次结构查询(没有START WITH ... CONNECT BY或CTE等价物)。因此,你需要以艰难和丑陋的方式做到这一点。
以下内容适用于您的3个级别,如果您需要在树中更深入,则会非常麻烦。这是Fiddle
SELECT C.MAILSHOT_ID
,C.MAILSHOT_PARENT
,C.MAILSHOT_NAME
,C.MAILSHOT_LEVEL
,CASE WHEN C.MAILSHOT_LEVEL = 0
THEN CAST(C.MAILSHOT_ID AS CHAR(4))
WHEN C.MAILSHOT_LEVEL = 1
THEN CONCAT(CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4)))
ELSE CONCAT(CAST(P.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4)))
END AS SORT_ORDER
FROM MAILSHOT C
LEFT OUTER JOIN
MAILSHOT P
ON P.MAILSHOT_ID = C.MAILSHOT_PARENT
ORDER BY CASE WHEN C.MAILSHOT_LEVEL = 0
THEN CAST(C.MAILSHOT_ID AS CHAR(4))
WHEN C.MAILSHOT_LEVEL = 1
THEN CONCAT(CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4)))
ELSE CONCAT(CAST(P.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4)))
END
答案 1 :(得分:1)
这是分层表的一个典型示例,它更容易在oracle中查询,但这不是重点。 @Declan_K给了你一个很好的答案来实现你想要的。如果您正在寻找一种替代方案,通过组织良好的输出可以使您略有不同,您可以尝试这种方法:
SELECT m1.mailshot_name AS lev1n ,
m1.mailshot_id AS lev1,
m1.mailshot_parent AS lev1p,
m2.mailshot_name AS lev2n,
m2.mailshot_id AS lev2,
m2.mailshot_parent AS lev2p,
m3.mailshot_name lev3n,
m3.mailshot_id lev3,
m3.mailshot_parent AS lev3p
FROM mailshot m1
LEFT JOIN mailshot m2 ON m2.mailshot_parent = m1.mailshot_id
LEFT JOIN mailshot m3 ON m3.mailshot_parent = m2.mailshot_id
WHERE m1.mailshot_parent = 0;
提供输出:
+----------+------+-------+-----------+------+-------+-------------+------+-------+
| lev1n | lev1 | lev1p | lev2n | lev2 | lev2p | lev3n | lev3 | lev3p |
+----------+------+-------+-----------+------+-------+-------------+------+-------+
| England | 49 | 0 | London | 140 | 49 | Wimbledon | 300 | 140 |
| England | 49 | 0 | London | 140 | 49 | Westminster | 310 | 140 |
| England | 49 | 0 | York | 149 | 49 | NULL | NULL | NULL |
| Scotland | 56 | 0 | Glasgow | 191 | 56 | NULL | NULL | NULL |
| Scotland | 56 | 0 | Edinburgh | 493 | 56 | NULL | NULL | NULL |
+----------+------+-------+-----------+------+-------+-------------+------+-------+
关于如何处理MySQL中的分层数据的好总结可以在这里找到:
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/