返回

MySQL UNION ALL 查询返回空结果?解决数据类型不兼容问题

mysql

引言

在使用 UNION ALL 子句将两个 MySQL 查询的结果合并时,有时可能会遇到空结果。这通常是由数据类型不兼容造成的。本文将深入探讨导致这种情况的原因,并提供解决此问题的有效方法。

问题:数据类型不兼容

MySQL 在执行 UNION ALL 查询时,会比较每个子查询中相同列的数据类型。如果数据类型不兼容,MySQL 将尝试进行类型转换。然而,这可能会导致精度丢失或结果为 NULL

在给定的示例中,子查询分别使用 json_object() 函数来构造 JSON 对象。此函数返回一个 JSON 对象,其类型为 JSON。MySQL 尝试将这两个 JSON 对象连接在一起,但由于它们没有明确定义的模式,因此 MySQL 无法确定如何进行连接。

解决方法:确保数据类型一致

要解决此问题,我们需要确保两个子查询返回相同的数据类型。一种方法是将 json_object() 函数的返回值转换为字符串:

SELECT json_arrayagg(CAST(obj AS CHAR)) as RESULT
FROM (
    SELECT 
        json_object(
            "points", json_arrayagg(json_array(
                            UNIX_TIMESTAMP(timestamping)*1000, 
                            CONVERT(ROUND(P1,4), DECIMAL(9,4))
             ))                                   
         ) AS obj
    FROM 
        mytable 
    WHERE 
        timestamping between '2021-10-01T00:00:00.000Z' 
    AND 
        '2022-05-10T23:59:59.999Z'

     UNION ALL 

    SELECT 
        json_object(
            "datapoints", json_arrayagg(json_array(
                            UNIX_TIMESTAMP(timestamping)*1000, 
                            CONVERT(ROUND(P2,4), DECIMAL(9,4))
               ))                                   
         ) AS obj
    FROM 
        mytable 
    WHERE 
        timestamping between '2021-10-01T00:00:00.000Z' 
    AND 
        '2022-05-10T23:59:59.999Z'
) x

通过将 JSON 对象转换为字符串,MySQL 现在可以将它们连接在一起,而不会出现数据类型不兼容的问题。

其他提示

  • 确保将 timestamping 列定义为 DATETIMETIMESTAMP 数据类型,以便 MySQL 可以正确比较它们。
  • 如果可能,请使用 UNION 代替 UNION ALL,因为 UNION 将删除重复结果。
  • 对于需要高性能的大型数据集,考虑使用视图或存储过程来预处理和存储数据,从而减少查询执行时间。

结论

通过理解数据类型不兼容问题,并采取必要的措施来确保两个子查询返回相同的数据类型,我们可以有效解决 UNION ALL 查询返回空结果的问题。通过遵循本文中概述的方法,您将能够确保 MySQL UNION ALL 查询始终返回预期的结果。

常见问题解答

1. 为什么 UNION ALL 在连接 JSON 对象时会失败?

答:因为 MySQL 无法确定如何连接具有不确定模式的两个 JSON 对象。将 JSON 对象转换为字符串可以解决此问题。

2. 除了类型转换外,还有什么其他因素会导致空结果?

答:其他因素包括:比较运算符不匹配、聚合函数返回不同的值或列别名冲突。

3. UNIONUNION ALL 之间有什么区别?

答:UNION 删除重复结果,而 UNION ALL 保留它们。

4. 什么时候使用 UNION 而不是 UNION ALL

答:当您需要删除重复结果或提高性能时,请使用 UNION

5. 如何使用视图或存储过程来提高性能?

答:视图和存储过程可以将复杂查询预处理并存储为对象,从而减少查询执行时间。