在MySQL中,在SELECT语句中设置一个变量

12

我正在使用这段代码,但它有一个错误:

SET @rejects = '';

SELECT *
FROM list
WHERE maker = 1
    AND by_ids IN ('10','11')
    AND country LIKE '%I%'
    AND (
        src IS NULL
        || src NOT IN (@rejects)
        AND checkSrc(src) = 'yes'
        AND SET @rejects = CONCAT(@rejects,',',src)
    );

引起这个问题的原因是什么?


能把“by_ids INT('10','11')”转换成“by_ids IN('10','11')”吗? - fedorqui
为什么在WHERE子句中使用AND SET @rejects = CONCAT(@rejects,',',src) - Ravindra Gullapalli
这就是我想要的,我想将每个搜索到的src的值连接到@rejects变量中。 - Andrew Eisenberg
1
不应该将 || 用作或运算符。 - mko
当你搜索“MySQL按最大/前n分组”或类似内容时,你可以看到一些示例 - 这是因为MySQL解决方案需要一些有趣的技巧(通常只是增加计数器)。 - user166390
2个回答

17
问题在于您不能在一个语句中同时使用 selectset,否则一定会出现语法错误。
select*from t where 1 and set@a=1;

如果您想在select中使用set,请使用冒号等于语法。更改如下:

错误1064(42000):您的SQL语法有误;请检查与您的MySQL服务器版本相对应的手册,以获取正确的语法使用方式,在“set@a=1”附近的第1行

select*from t where 1 and set@a=1;

转换成:

select*,@a:=1 from t where 1;

这是如何在每行更新变量的:

upon each 表示“每次”:

create table t(id int); insert t values(1),(2),(3);
set@a=0;
select@a:=id from t;
+--------+
| @a:=id |
+--------+
|      1 |
|      2 |
|      3 |
+--------+

而且你甚至可以执行concat操作:

set@a='0';
select @a:=concat(@a,',',id)from t;
+-----------------------+
| @a:=concat(@a,',',id) |
+-----------------------+
| 0,1                   |
| 0,1,2                 |
| 0,1,2,3               |
+-----------------------+
或者没有前导0的concat:
set@a='';
select @a:=concat(@a,if(@a='','',','),id)from t;
+------------------------------------+
| @a:=concat(@a,if(@a='','',','),id) |
+------------------------------------+
| 1                                  |
| 1,2                                |
| 1,2,3                              |
+------------------------------------+

然而,该手册明确指出这是危险的:link

...您永远不应将值分配给用户变量并在同一语句中读取该值...

...您可能会得到期望的结果,但不能保证

...涉及用户变量的表达式计算顺序未定义

这也曾在Xaprb上提到过。

最后,如果您正在做一些奇怪的事情,如将不同类型的值分配给变量等,请查看手册以确保您了解复杂的机制。


“你不应该在同一语句中给用户变量赋值并读取该值…” 这个建议让我省去了很多尝试和错误。 - Philipp

2

那么,您可以像这样编写您的查询。

SET @rejects = '';
SELECT @rejects = CONCAT(@rejects,',',src) FROM list WHERE maker = 1 AND by_ids IN ('10','11') AND country LIKE '%I%' AND 
(src IS NULL OR src NOT IN (@rejects) AND checkSrc(src) = 'yes');
SELECT @rejects;

1
你期望的输出是什么?如果src为空,可能会出现问题。你能发布一下你的表结构和期望的输出吗? - Ravindra Gullapalli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接