Mysql 为什么不是';t用户定义变量工作
我试图在if语句中使用子查询。 如果我这样做,它的工作Mysql 为什么不是';t用户定义变量工作,mysql,Mysql,我试图在if语句中使用子查询。 如果我这样做,它的工作 SELECT `Currency`, IF((SELECT `id` FROM `upload_currency` WHERE `CurrencyText`=`Currency`) > 0,(SELECT `id` FROM `upload_currency` WHERE `CurrencyText`=`Currency`),1) FROM `upload_salesinvoice` 我得到了输出 1,1,3,1美元,2,1,1欧元
SELECT `Currency`, IF((SELECT `id` FROM `upload_currency` WHERE `CurrencyText`=`Currency`) > 0,(SELECT `id` FROM `upload_currency` WHERE `CurrencyText`=`Currency`),1) FROM `upload_salesinvoice`
我得到了输出
1,1,3,1美元,2,1,1欧元,这是正确的
然而,如果我试图让我的查询像这样更有效,它会给我所有的1
SELECT `Currency`, IF(@val:=(SELECT `id` FROM `upload_currency` WHERE `CurrencyText`=`Currency`) > 0,@val,1) FROM `upload_salesinvoice`
我将进一步解释一下,我有一个名为upload_currency的表,在这个表中我有这个布局
id 1,货币文本GBP
id 2,货币文本欧元
id 3,货币文本美元
因此,我的subselect应该返回1表示英镑,或1表示空字符串,2表示欧元,3表示美元,但第二个查询失败,并给出了所有1
因此,看起来我的用户定义变量由于某种原因失败了。根据mysql手册: 一般来说,除了SET语句之外,您不应该 为用户变量赋值并读取同一变量中的值 声明 编辑:
SELECT `Currency`, @val := (
SELECT `id` FROM `upload_currency`
WHERE `CurrencyText`=`Currency`
),
IF(@val > 0,@val,1) FROM `upload_salesinvoice`;
根据mysql手册: 一般来说,除了SET语句之外,您不应该 为用户变量赋值并读取同一变量中的值 声明 编辑:
SELECT `Currency`, @val := (
SELECT `id` FROM `upload_currency`
WHERE `CurrencyText`=`Currency`
),
IF(@val > 0,@val,1) FROM `upload_salesinvoice`;
查询不起作用的原因是将比较值赋给变量;对于MySQL,分配的内容如下
@val:=((SELECT `id` FROM `upload_currency` WHERE `CurrencyText`=`Currency`) > 0)
它是1或0,而不是id
。因此,您必须添加括号并使用
IF( (@val:=(SELECT `id` FROM `upload_currency` WHERE `CurrencyText`=`Currency`))
> 0, @val, 1)
也就是说:我认为您试图以一种非常复杂的方式做的实际上只是一个左连接
:
select u.currency, coalesce(c.id,1)
from upload_salesinvoice u
left join upload_currency c
on c.CurrencyText=u.Currency
它也会更快 查询不起作用的原因是将比较值赋给变量;对于MySQL,分配的内容如下
@val:=((SELECT `id` FROM `upload_currency` WHERE `CurrencyText`=`Currency`) > 0)
它是1或0,而不是id
。因此,您必须添加括号并使用
IF( (@val:=(SELECT `id` FROM `upload_currency` WHERE `CurrencyText`=`Currency`))
> 0, @val, 1)
也就是说:我认为您试图以一种非常复杂的方式做的实际上只是一个左连接
:
select u.currency, coalesce(c.id,1)
from upload_salesinvoice u
left join upload_currency c
on c.CurrencyText=u.Currency
它也会更快 这将不起作用,因为val在每行上都在更改。我正在检查多行,因此val将在每行上更改。您的方法将在select之前将其固定为一个val。我正在检查upload_SalesInvoice中的多行。谢谢你的回答有效,但我希望能像Solarflare那样在一行中完成。这样做的原因是我还需要将它插入到另一个查询中。对于插入选择,插入中的字段数与选择中的字段数相同。不过谢谢。这不起作用,因为val每行都在更改。我正在检查多行,因此val将在每行上更改。您的方法将在select之前将其固定为一个val。我正在检查upload_SalesInvoice中的多行。谢谢你的回答有效,但我希望能像Solarflare那样在一行中完成。这样做的原因是我还需要将它插入到另一个查询中。对于插入选择,插入中的字段数与选择中的字段数相同。不过谢谢。是的,我的每个答案都得1分。谢谢你的回答。那些讨厌的小括号很重要。要回答您关于我为什么不使用左连接的问题,我所显示的查询是一个更大的insert select查询的一部分,在这个查询中,左连接不会很好地工作。是的,我只是每个答案都得到1。谢谢你的回答。那些讨厌的小括号很重要。要回答您关于我为什么不使用左连接的问题,我所显示的查询是一个更大的insert select查询的一部分,在这个查询中,左连接不会很好地工作。请注意,以这种方式使用变量实际上不会使您的查询更有效率。优化器应该意识到重复的子查询是重复的。。。并且应该隐式地重用该值,而不是执行两次子查询。我不知道这一点,但无论如何还是要感谢您。请注意,以这种方式使用变量实际上不会使您的查询更高效。优化器应该意识到重复的子查询是重复的。。。并且应该隐式地重用该值,而不是执行两次子查询。我不知道这一点,不过还是要谢谢你。