【问题标题】:How to use a variable as the result of a group_concat in a IN()如何使用变量作为 IN() 中 group_concat 的结果
【发布时间】:2015-03-22 03:48:59
【问题描述】:

这些是我的表(简化):

mytable
--------------------
`pid` int(11) NOT NULL AUTO_INCREMENT
`mydate` date NOT NULL,

pictures
--------------------
`pid` int(11) NOT NULL AUTO_INCREMENT
`image_name` varchar(255)

pictures_2014
--------------------
`pid` int(11) NOT NULL AUTO_INCREMENT
`image_name` varchar(255)

这是我的代码:

SET AUTOCOMMIT=0;
START TRANSACTION;
SELECT @pids := GROUP_CONCAT(CONVERT(pid , CHAR(8)))
FROM  `mytable`
WHERE  `mydate`
BETWEEN  '2014-01-01'
AND  '2014-10-31';
INSERT INTO  pictures_2014 SELECT * FROM `pictures` where pid in(@pids);
COMMIT;

只有一个项目被插入到图片_2014 中,即逗号分隔列表中的第一个项目。

我期望的结果是所有与我的第一个查询匹配的 4111 行(至少在 pictures 中的那些)都将被复制。 我知道至少在 phpmyadmin 中显示的 group_concat 中的前 6 个 pid 存在于表格图片中 我还尝试在我的第一个查询中添加 LIMIT 0,100 以查看它是否是一个可变长度问题,但我仍然只得到一个结果。

【问题讨论】:

    标签: mysql transactions


    【解决方案1】:

    您所做的工作比您必须做的要多 - 您将遇到将多个值组合成单个字符串的所有麻烦,现在您遇到了问题,因为IN 想要处理多个值。

    为什么不这样:

    SET AUTOCOMMIT=0;
    START TRANSACTION;
    INSERT INTO  pictures_2014 SELECT * FROM `pictures`
    where pid in(
      SELECT pid
      FROM  `mytable`
      WHERE  `mydate`
      BETWEEN  '2014-01-01'
      AND  '2014-10-31');
    COMMIT;
    

    【讨论】:

    • 在图片表结果和mytable结果中都有4111个结果,你建议的方法超时
    • @Traveling_Monk - 4111 个结果不是大量数据。如果需要很长时间来处理,您可能需要寻找一些关于分析性能和索引的一般指南
    • 事实是@pids 没有正确处理,我想知道为什么。您实际编写的查询将有 4111x4111=16900321 个结果,子查询将在每次主查询时运行。
    【解决方案2】:

    好的,这就是我学到的: 正在设置的变量被解释为 '321,654,987' 而不是 '321','654','987' (Thanks@John Woo)

    通过将 IN() 更改为 FIND_IN_SET() 我得到了正确的结果!

    SET AUTOCOMMIT=0;
    START TRANSACTION;
    SELECT @pids := GROUP_CONCAT(CONVERT(pid , CHAR(8)))
    FROM  `mytable`
    WHERE  `mydate`
    BETWEEN  '2014-01-01'
    AND  '2014-10-31';
    INSERT INTO  pictures_2014 SELECT * FROM `pictures` where FIND_IN_SET(pid,@pids);
    COMMIT;
    

    【讨论】:

    • 经过进一步研究 FIND_IN_SET 不适用于我的目的,似乎 1024 个字符是 FIND_IN_SET(str,strlist) 中第二个参数中的最大可用大小,因为我的 pid 是 6 位数字并且146 条记录是此事务将插入的最大值,因此 6 + 1 用于逗号,2 用于引号 ((6+1)*146)+2 =1024
    • ok 另一个测试发现限制不在于函数,而在于变量的长度... SELECT LENGTH( @pids ) ==1024
    猜你喜欢
    • 2013-11-28
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 2016-09-09
    • 2011-10-30
    • 1970-01-01
    • 2023-01-13
    • 2019-12-10
    相关资源
    最近更新 更多