比如这样的查询:
SELECT * FROM sys_address three LEFT JOIN sys_address two ON three.parent_code = two.code LEFT JOIN sys_address o ON two.parent_code = o.code WHERE three.CODE = 110101
返回是这样的:
"110101" "东城区" "110100" "3" "110100" "市辖区" "110000" "2" "110000" "北京市" "" "1"
有办法做到返回这样的结构么:
"110101" "东城区" "110100" "3" "110100" "市辖区" "110000" "2" "110000" "北京市" "" "1"
![]() | 1 Yuicon OP 我自己倒是想到一种办法 就是有点蛋疼 非常长 |
![]() | 2 Yuicon OP ``` SELECT three.* FROM cdshopping.sys_address three WHERE three.CODE = 110101 UNION SELECT two.* FROM cdshopping.sys_address three LEFT JOIN cdshopping.sys_address two ON three.parent_code = two.code WHERE three.CODE = 110101 UNION SELECT o.* FROM cdshopping.sys_address three LEFT JOIN cdshopping.sys_address two ON three.parent_code = two.code LEFT JOIN cdshopping.sys_address o ON two.parent_code = o.code WHERE three.CODE = 110101 ``` |
![]() | 3 Gatsbywl 2019-06-28 12:22:17 +08:00 SELECT * FROM sys_address WHERE CODE IN ( -- 3 级地名的 code 110101, -- 选择上一步的 parent_code (SELECT three.parent_code FROM testdb.sys_address three WHERE three.CODE = 110101), -- 继续选择上一步的 parent_code, (SELECT parent_code FROM sys_address WHERE CODE = (SELECT three.parent_code FROM testdb.sys_address three WHERE three.CODE = 110101)) -- 如果还有需求选择 再上一级的'中国',重复上一个步骤即可 ) |
![]() | 4 Gatsbywl 2019-06-28 12:26:07 +08:00 ![]() 我暂时只能想到这种思路,其实就是根据最低级区域的 代号 往上寻根,所以每次 WHERE code = 上一步的 parent_code |
![]() | 5 reus 2019-06-28 12:26:21 +08:00 用 PostgreSQL 或者 MySQL 8 的 recursive CTE |
![]() | 7 meetocean 2019-06-28 13:01:33 +08:00 ![]() 亲自测试可用: ( SELECT three.id as id3, three.title title3 FROM plots three LEFT JOIN plots two ON three.parent_id = two.id LEFT JOIN plots one ON two.parent_id = one.id WHERE three.id = 7 ) UNION ( SELECT two.id as id2, two.title title2 FROM plots three LEFT JOIN plots two ON three.parent_id = two.id LEFT JOIN plots one ON two.parent_id = one.id WHERE three.id = 7 ) UNION ( SELECT one.id as id1, one.title title1 FROM plots three LEFT JOIN plots two ON three.parent_id = two.id LEFT JOIN plots one ON two.parent_id = one.id WHERE three.id = 7 ) 按照这个思路,把 SQL 修改一下即可。 |
![]() | 8 meetocean 2019-06-28 13:11:07 +08:00 这是硬查询,如果你不需要数据库里的三行,而是三行字符串,那么还有方法,重组字符串。 |
![]() | 9 JQZhang 2019-06-28 13:20:32 +08:00 ![]() 还是喜欢 Oracle 的 connect by,你可以搜一下 mysql 仿写的 connect by |
12 Alexisused 2019-06-28 13:53:13 +08:00 意义在哪里? |
13 whl619969187 2019-06-28 16:22:18 +08:00 就是递归查询嘛,mysql 8 好像支持 oracle 支持 其他没用过 |
![]() | 14 1ffree 2019-06-28 16:32:07 +08:00 说明表设计有问题。 要么做个冗余, 要么多行取出来内存里做处理 |
![]() | 15 oaix 2019-06-28 16:49:54 +08:00 code 看起来有编码规范,所以只要 where code in ('110101', '110100', '110000') |
![]() | 16 Yuicon OP @Alexisused ...... 因为这实际是三条记录我当然希望返回的三个对象 |
![]() | 18 meetocean 2019-06-28 17:10:00 +08:00 @oaix 从楼主的题目,可推断数据表是层级表,并且只有三级,分别是省、市、区。 用户给定的查询条件就是给定叶子结点(没有子节点的节点)的一个具体值“ 110000 ”。 根据这个条件得到上级(市)与上上级(省)数据。 |
![]() | 19 Yuicon OP @whl619969187 比起引入存储过程或者自定义函数我宁愿查三次。。。 |
21 saulshao 2019-06-28 17:55:18 +08:00 这个建议是要多次查询这个表,不建议完全用 SQL. |
![]() | 22 Takamine 2019-06-29 08:56:53 +08:00 第一,我不会这么写; 第二,我不会这么写。:doge: 第三,作为 CRUDboy 我会把这个放到业务层。 |