mysql多层查询

本文探讨了如何避免MySQL中GROUP_CONCAT函数截断问题,通过调整group_concat_max_len设置,并解析如何在JPA原生SQL中正确转义变量。讨论了父子ID查询的上下层操作,以及解决查询中特定字符串转义的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

附件:city.sql - djmg
mysql查询某节点下层的所有元素节点:

select parentId, areaId, areaCode,areaName, level, center
	  from city_area
	  where find_in_set(areaId,
		 	(select GROUP_CONCAT(childrenIds) from (
			 	select (
			     select @childrenIds:=GROUP_CONCAT(areaId) from city_area where FIND_IN_SET(parentId, @childrenIds)) as childrenIds
--			     ,CEILING( LENGTH(@childrenIds) / 5 )
		        from (select @childrenIds:=?) var,city_area c where  @childrenIds is not null
			) A )
		)
--	and areaName like '%区%';

mysql查询某节点上层的所有元素节点:

select parentId, areaId, areaCode,areaName, level, center
	  from city_area
	  where find_in_set(areaId,
		 	(select GROUP_CONCAT(childrenIds) from (
			 	select (
			     select @childrenIds:=GROUP_CONCAT(parentId) from city_area where FIND_IN_SET(areaId, @childrenIds)) as childrenIds
--			     ,CEILING( LENGTH(@childrenIds) / 5 )
		        from (select @childrenIds:=?) var,city_area c where  @childrenIds is not null
			) A )
		)
--	and areaName like '%区%';

两个查询的不同点在于最内层的查询将父子Id位置对换了一下(select @childrenIds:=GROUP_CONCAT(parentId) from city_area where FIND_IN_SET(areaId, @childrenIds)) as childrenIds(select @childrenIds:=GROUP_CONCAT(areaId) from city_area where FIND_IN_SET(parentId, @childrenIds)) as childrenIds

问题:

  1. group_concat函数被截断的问题

mysql的 group_concat 函数默认返回1024个字节长度,超过长度的会被截断;
命令行下输入:SET GLOBAL group_concat_max_len=1024000;
or SET SESSION group_concat_max_len=1024000;

  1. jpa原生sql':'转义问题

字符:在jpa原生sql会被看作是变量的前缀@childrenIds:=? ==> @childrenIds\\:=?

### 如何在 MySQL 中执行多层 JSON 查询 #### 创建带有 JSON 列的数据表 为了展示如何进行多层 JSON 查询,先创建一个包含 JSON 类型列 `data` 的表格 `json_data`[^1]。 ```sql CREATE TABLE json_data ( id INT AUTO_INCREMENT PRIMARY KEY, data JSON NOT NULL ); ``` #### 插入多层结构的 JSON 数据 向上述创建好的 `json_data` 表格中插入一些具有嵌套层次结构的 JSON 文档作为测试数据: ```sql INSERT INTO json_data (data) VALUES ('{ "employee": { "name": "张三", "department": "研发部", "address": { "city": "北京", "street": "中关村大街" }, "projects": [ {"project_name": "项目A", "start_date": "2023-01-01"}, {"project_name": "项目B", "start_date": "2023-06-01"} ] } }'); ``` #### 执行单层路径查询 对于简单的键值对查询,可以直接利用箭头操作符 (`->`) 来访问指定路径下的值。例如要获取员工的名字可以这样做: ```sql SELECT data -> '$.employee.name' AS employee_name FROM json_data; ``` 这将会返回如下结果: | employee_name | |---------------| | "张三" | 注意这里的字符串会被加上双引号表示这是一个 JSON 字符串类型的结果;如果想要去掉这些额外的引号,则可使用 `->>` 运算符代替 `->`. #### 多层路径查询 当涉及到更深层次的对象属性时,只需继续扩展路径即可。比如要获得城市名称: ```sql SELECT data ->> '$.employee.address.city' as city FROM json_data; ``` 此命令将输出: | city | |----------| | 北京 | #### 数组中的对象查询 假设现在希望找到参与特定项目的员工姓名,即遍历数组并匹配某个条件。此时需要用到函数 `JSON_CONTAINS_PATH()` 和/或其他辅助函数如 `JSON_UNQUOTE()`, `JSON_EXTRACT()` 等来处理复杂情况。下面是一个例子,它会找出所有参加了“项目A”的员工名字: ```sql SELECT JSON_UNQUOTE(data->>'$.employee.name') AS name FROM json_data WHERE JSON_CONTAINS(JSON_EXTRACT(data,'$.employee.projects[*].project_name'), '"项目A"', ''); ``` 这段SQL语句首先提取了所有的子项列表,接着判断是否存在目标字符串,并最终取出了符合条件记录里的员工姓名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值