为什么这个递归concat产生:数据太长

问题描述 投票:0回答:1

我在MySQL 8上有这个表:

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导致以下错误:

错误:ER_DATA_TOO_LONG:第7行的列concat(id, '')数据太长

为什么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有问题。

mysql concat varchar recursive-query
1个回答
3
投票

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

Update of your demo

© www.soinside.com 2019 - 2024. All rights reserved.