我有以下表格:

persons:
- personid: int not null
- personname: varchar(200) not null

parents:
- parentid: int not null
- personid: int not null

一个人可能有子元素,在这种情况下,parents表中有行,其中每一行标识一个父/子关系.

我现在有以下递归查询:

        WITH RECURSIVE cte (personid, parentid) as (
            -- Anchor query
            SELECT
                personid AS personid,
                NULL AS parentid
            FROM
                persons
            WHERE
                personid = ?
            UNION ALL
            -- Recursive query
            SELECT
                p.personid,
                p.parentid
            FROM
                parents p
            INNER JOIN
                cte ON p.parentid = cte.personid
        )
        SELECT
            parentid,
            personid
        FROM
            cte

锚点行被赋予person的ID作为开始.我希望这个查询递归地 Select 那个人以及他的所有子元素.

但是它不起作用:查询返回预期的行数,但是parentid字段始终为空(!),除了第一行的值是NULL(这正是我想要的).personid列的值对于每一行似乎都是正确的.

parentid的值怎么可能是空的?我做错了什么?

我使用的是MariaDB 10.5.19.MySQL 8.0.27表现出相同的行为.

推荐答案

问题似乎出在递归查询的第一部分:

        SELECT
            personid AS personid,
            NULL AS parentid
        ...

Parentid的数据类型由此决定.该类型变为空,而不是所需的int.在UNION中,一列只能有一个名称和一种数据类型,这些名称和数据类型适用于UNION中其他查询附加的所有后续行.

当递归查询的第二部分try 将整数放入该列时,它会失败.

当我测试在严格模式下运行的给定查询时,我收到以下错误:

错误1406(22001):第1行的列‘parentid’的数据太长

如果在没有严格模式的情况下运行查询,则该值将被截断为某个大约为零的值.我在MySQL8.0上进行了测试,结果得了0x分.

MariaDB可能有不同的行为.我们都应该停止将MariaDB和MySQL视为兼容的产品.他们有越来越多的不相容行为.它们现在实际上是完全不同的产品.

解决方案是确保基本情况使用正确的数据类型定义该列:

        SELECT
            personid AS personid,
            CAST(NULL AS UNSIGNED) AS parentid
        ...

Mysql相关问答推荐

使用JSON_CONTAINS搜索多个值的原理

MySQL逻辑全部

MySQL中如何对字符串进行算术运算?

没有 ORDER BY 的查询性能很高,有 ORDER BY 的查询速度慢得像爬行一样

mysql 代码给我的外键格式不正确

GoRM中行最大值查询返回"0"

MySQL MDL(元数据锁)为什么会导致死锁?

「已解决」MySQL 连接在 vb6 上出现运行时错误 -2147467259 (80004005),但在 VBA Excel 上工作

拆分列值并适当地返回拆分值

MySQL:根据条件查找某些用户的行位置

从 SQL 中的左连接和内连接中减go 计数

了解 SQL 中的元组语法

MySQL Group By 和 Sum 其他列的总值

MySQL - 如何在 INSERT 语句中将字符串值解析为 DATETIME 格式?

如何使用 phpmyadmin 复制数据库?

问号在 MySQL 中WHERE column = ?的意义是什么?

MySQL ORDER BY rand(),名称为 ASC

如何从两个不同的日期获得年份差异?

比较 MySQL 中的日期忽略 DateTime 字段的时间部分

我在哪里可以下载 mysql jdbc jar?