MySQL将多条无关联SQL查询结果合并到一个JSON对象中
在数据统计场景中,常遇到需要同时获取多个无关联表的数据并封装为一个结果返回给前端的情况。本文演示如何通过 MySQL 的 UNION ALL 语法将分散在不同表中的统计指标(如总订单数和分销记录数)合并为单行数据,并结合 JSON_OBJECT 函数将其格式化为标准的 JSON 键值对对象,从而简化前端的数据处理逻辑。
实现方案与操作顺序
假设我们需要统计当天的总订单数和总分销记录数。由于这两项数据分别存储在 order(订单表)和 record(分销记录表)中,且表之间没有直接的关联条件,简单的 JOIN 无法直接实现单行输出。以下是完整的实现步骤:
第1步:基础数据统计查询
首先,确认两个独立的统计查询能够正确执行。这有助于验证数据范围和过滤条件的准确性。
- 统计当天总订单数:
SELECT COUNT(1) AS total_count
FROM `order`
WHERE DATE_FORMAT(order_create_time, '%Y-%m-%d') = '2024-05-20';
- 统计当天分销记录总数:
SELECT COUNT(1) AS record_count
FROM `record`
WHERE DATE_FORMAT(create_time, '%Y-%m-%d') = '2024-05-20';
第2步:使用 UNION ALL 对齐字段
为了实现单行输出,需要将两个查询的结果“对齐”。核心思路是:
在查询总订单数时,补充一列为空的或为0的分销记录数列;
在查询总分销记录数时,补充一列为空的或为0的订单数列。
然后通过 UNION ALL 将两者上下连接。
SELECT
(SELECT COUNT(1) FROM `order` WHERE DATE_FORMAT(order_create_time, '%Y-%m-%d') = '2024-05-20') AS total_count,
0 AS record_count
UNION ALL
SELECT
0 AS total_count,
(SELECT COUNT(1) FROM `record` WHERE DATE_FORMAT(create_time, '%Y-%m-%d') = '2024-05-20') AS record_count;
第3步:外层求和与 JSON 格式化
由于上一步产生的两行数据中,同一列只有一个非零值,另一个为0。因此可以通过在外层包裹一个求和查询(SUM()),将两行压缩为一行。最后,使用 JSON_OBJECT 函数将单行数据转换为键值对结构。
SELECT
JSON_OBJECT(
'totalCouut', sub.total_count,
'recordCount', sub.record_count
) AS result_json
FROM (
SELECT
SUM(total_count) AS total_count,
SUM(record_count) AS record_count
FROM (
SELECT
(SELECT COUNT(1) FROM `order` WHERE DATE_FORMAT(order_create_time, '%Y-%m-%d') = '2024-05-20') AS total_count,
0 AS record_count
UNION ALL
SELECT
0 AS total_count,
(SELECT COUNT(1) FROM `record` WHERE DATE_FORMAT(create_time, '%Y-%m-%d') = '2024-05-20') AS record_count
) AS combined_data
) AS sub;
技术细节与注意事项
- 别名一致性:在子查询和联合查询中,务必确保同名列的别名(如
total_count)完全一致,否则可能导致SUM()计算错位。 - 性能优化:上述示例使用了子查询内联的方式,对于高并发场景,若
DATE_FORMAT导致索引失效,建议直接使用范围查询(例如order_create_time >= '...' AND order_create_time <= '...')以提升效率。 - 空值处理:如果表可能为空,
COUNT(1)仍会返回0,不会返回 NULL,这符合多数前端展示需求。如果需要保留 NULL 状态,可将填充的 0 改为 NULL。
总结
以上就是利用 MySQL 将多条不同 SQL 查询结果合并并封装到 JSON 对象的详细内容。这种方法巧妙地利用了 UNION ALL 的行扩展特性与 SUM() 的列压缩特性,完美解决了非关联数据的统一输出问题。更多关于 MySQL 复杂查询技巧的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













