为什么这个递归连接产生:数据太长
Why this recursive concat produces: Data too long
我在 MySQL 8:
上有这个 table
create table tbl(id varchar(2), val int);
insert into tbl values ('A', 1), ('B', 2), ('C', 3), ('D', 4), ('E', 5);
以下查询应找出哪些记录集的值加起来不大于 6(不考虑顺序的重要性):
with recursive cte(greatest_id, ids, total) as (
select id,
concat(id, ''),
val
from tbl
union all
select tbl.id,
concat(cte.ids, tbl.id),
cte.total + tbl.val
from cte
inner join tbl
on tbl.id > cte.greatest_id
and cte.total + tbl.val <= 6
)
select ids, total from cte
Running it 导致以下错误:
Error: ER_DATA_TOO_LONG: Data too long for column concat(id, '')
at row 7
为什么 MySQL 会产生这个错误?
有关信息,所需的输出如下:
IDS | TOTAL
----+------
A | 1
B | 2
C | 3
D | 4
E | 5
AB | 3
AC | 4
AD | 5
AE | 6
BC | 5
BD | 6
ABC | 6
我想知道 MySQL 是根据哪个(已记录?)规则在此处产生此错误的。
相比之下,查询在 PostgreSQL 和 Oracle 上运行良好(使用它们的语法变体),所以我不太明白 为什么 MySQL 有问题有了它。
A long way down the MySQL 8 CTE manual page 是一个显示您遇到的问题的示例。基本上,问题是您的 ids
列对于分配给它的 ABC
值来说太窄了,因为它的宽度来自 CTE 的非递归部分(实际上是 id
即 2 个字符)。您可以使用 CAST
解决该问题,使其宽度足够大以适应所有结果,例如:
with recursive cte(greatest_id, ids, total) as (
select id,
CAST(id AS CHAR(5)) AS ids,
val
from tbl
union all
select tbl.id,
concat(cte.ids, tbl.id),
cte.total + tbl.val
from cte
inner join tbl
on tbl.id > cte.greatest_id
and cte.total + tbl.val <= 6
)
select ids, total from cte
我在 MySQL 8:
上有这个 tablecreate table tbl(id varchar(2), val int);
insert into tbl values ('A', 1), ('B', 2), ('C', 3), ('D', 4), ('E', 5);
以下查询应找出哪些记录集的值加起来不大于 6(不考虑顺序的重要性):
with recursive cte(greatest_id, ids, total) as (
select id,
concat(id, ''),
val
from tbl
union all
select tbl.id,
concat(cte.ids, tbl.id),
cte.total + tbl.val
from cte
inner join tbl
on tbl.id > cte.greatest_id
and cte.total + tbl.val <= 6
)
select ids, total from cte
Running it 导致以下错误:
Error: ER_DATA_TOO_LONG: Data too long for column
concat(id, '')
at row 7
为什么 MySQL 会产生这个错误?
有关信息,所需的输出如下:
IDS | TOTAL
----+------
A | 1
B | 2
C | 3
D | 4
E | 5
AB | 3
AC | 4
AD | 5
AE | 6
BC | 5
BD | 6
ABC | 6
我想知道 MySQL 是根据哪个(已记录?)规则在此处产生此错误的。
相比之下,查询在 PostgreSQL 和 Oracle 上运行良好(使用它们的语法变体),所以我不太明白 为什么 MySQL 有问题有了它。
A long way down the MySQL 8 CTE manual page 是一个显示您遇到的问题的示例。基本上,问题是您的 ids
列对于分配给它的 ABC
值来说太窄了,因为它的宽度来自 CTE 的非递归部分(实际上是 id
即 2 个字符)。您可以使用 CAST
解决该问题,使其宽度足够大以适应所有结果,例如:
with recursive cte(greatest_id, ids, total) as (
select id,
CAST(id AS CHAR(5)) AS ids,
val
from tbl
union all
select tbl.id,
concat(cte.ids, tbl.id),
cte.total + tbl.val
from cte
inner join tbl
on tbl.id > cte.greatest_id
and cte.total + tbl.val <= 6
)
select ids, total from cte