带有GROUP_CONCAT和IN子句的mysql存储过程构造

时间:2014-06-14 08:31:10

标签: mysql sql stored-procedures

出于某种原因,我需要在多步骤(非常大的行和很多连接)中爆炸查询,我知道它可以像SELECT IN(子查询)那样执行查询,但它不是我需要实现的。< /强>

如何构造我的查询到步骤,其中查询2可以使用带有IN子句的查询1的结果(不使用临时表);预期查询2应如下所示:select otherstuff where foo IN(id,id,id,id,longlistid,)

查询1 =&gt;选择stuf作为结果1 查询2 =&gt;选择otherstuf foo IN(result1)

我想用快捷方式@不知道是否合适,这是我的尝试:

 CREATE PROCEDURE `exemple`()
    BEGIN

     SELECT @query1 := 
    `id`  FROM `table`
    WHERE `stuf`= 'cat'
    UNION ALL SELECT `id`
    FROM `table`
    WHERE `dog`= 'hard' ;

    SELECT please FROM help WHERE me IN(@query1) ;

    END

IN子句似乎不正确..

另一次尝试,将结果存储在声明的语言环境变量中:

CREATE PROCEDURE `exemple`()
    BEGIN

     DECLARE resultquery1 VARCHAR(5000);

    SELECT 
    `id`  FROM `table`
    WHERE `stuf`= 'cat'
    UNION ALL SELECT `id`
    FROM `table`
    WHERE `dog`= 'hard' 
    INTO resultquery1 ;

    SELECT please FROM help WHERE me IN(resultquery1) ;

    END

没有,我得到了这个逻辑错误: 错误代码:1172。结果由多行组成

的问候, 杰斯

3 个答案:

答案 0 :(得分:1)

使用Temporary Table代替并在该表中插入query1值。然后在你的query2中你可以直接从临时表中获取数据;如下(代码示例)

CREATE PROCEDURE `exemple`()
BEGIN

create temporary table temptest(col varchar(20));
insert into temptest
 SELECT `foo`  FROM `table`
WHERE `stuf`= 'cat'
UNION ALL SELECT `bar`
FROM `table`
WHERE `dog`= 'hard' ;

SELECT please FROM help WHERE me IN (select distinct col from temptest) ;

DROP TABLE temptest;
END

修改

您可能根本不需要临时表。根据您的帖子说明,您可以直接在IN子句中包含查询,如下所示。希望这会有所帮助。

 SELECT please FROM help 
 WHERE me IN (
     SELECT `foo`  FROM `table`
    WHERE `stuf`= 'cat'
    UNION ALL SELECT `bar`
    FROM `table`
    WHERE `dog`= 'hard'
    ) ;

最终编辑:

inlist是一个逗号分隔值,你不能简单地存储就像你正在尝试的那样,因为它是你试图存储的标量变量而且它是不正确的;

你可能会像下面那样做一些小技巧并存储它,但不保证能够正常工作。

set @inlist := (
select group_concat(unitid)
from (
SELECT unitid, 1 as 'ID'  FROM teachers
    WHERE username= 'abcdced'
    UNION ALL 
    SELECT unitid, 1 as 'ID'  FROM teachers
    WHERE username= 'harikas'
) x
group by ID);

此外,我不确定是谁告诉你,通过变量将是有效的。

我可能同意TEMPORARY表可能会根据您的情况提出一些问题但是 我给出的子查询选项(或者Gordon在下面的答案中提供的建议)将比你尝试的方式更有效率。至少它不会产生获取和存储到变量中的成本(如果它完全有效)。

答案 1 :(得分:1)

我在这里添加答案要在最终编辑中关注@Rahul正确答案,对于需要实现此特定情况的人(当子查询不能表现得很好时), 这是使用mysql GROUP_CONCAT和CONCAT函数的过程的最终形式:
temp是用于存储第一个结果的声明的局部变量
SET SESSION组concat以避免group_concat限制长度

    CREATE PROCEDURE `exemple`()
    BEGIN

    DECLARE temp VARCHAR(10000); 
    SET SESSION group_concat_max_len = 100000; 

    SELECT GROUP_CONCAT(foo) FROM bar
    WHERE cible = x GROUP BY cible INTO temp; 

    SET @S = CONCAT
   (
    "SELECT * FROM anothertable WHERE whatyouwant IN(", temp," ) "
   );

    PREPARE STMT FROM @S;
    EXECUTE STMT;   

    END

答案 2 :(得分:0)

通常,最有效的方法是使用where子句中的两个条件:

select please
from help h
where exists (select 1
              from table t1
              where stuf = 'cat' and h.me = t1.foo
             ) or
      exists (select 1
              from table t1
              where dog = 'hard' and h.me = t1.bar
             );

这些查询可以利用子查询中使用的表上的索引:table(foo, cat)table(bar, hard)