具有AVG功能的空集UNION和任何非空集

时间:2013-01-18 15:24:41

标签: mysql sql database

这是我的第一个问题,所以请耐心等待.. :)

我们是两个开发人员,两者都具有相同的表和值的MySql DB。

其中一个是MySql 5.5版,并且正常工作(显然),其他开发人员告诉我。

在我的机器上使用MySql 5.1.44(基本的MAMP安装)我有以下奇怪的问题。

一个非常大的查询(不是我的)失败,错误“列'xd'不能为空”。

删除碎片我把它缩小到这个:

select xd, avg(media) from questionario_punteggi where somefield = 1 union select 1,2

注意,没有记录,somefield = 1 所以第一个选择返回一个空集

我们有一个带有AVG()函数的SELECT,它返回一个空集UNION另一个返回一些东西的SELECT(1,2只是我现在放的随机值作为例子)

  • 如果我删除了AVG(),则查询有效。
  • 如果我删除xd(以及右边的1,2中的2),查询将起作用。
  • 如果删除UNION,查询将起作用。
  • 如果我使用somefield = 1设置了一些记录,则查询有效。
  • 在另一台机器5.5上查询有效。

否则错误是:

1048 - 列'xd'不能为空

字段是:

`xd` char(3) NOT NULL DEFAULT '001',
`media` decimal(7,4) NOT NULL DEFAULT '0.0000',
`somefield` tinyint(4) NOT NULL DEFAULT '0',

天哪。有帮助吗?感谢。

更新

据我所知,MySql< = 5.1中的BUG是在MySql 5.5之前修复的。我没有详细信息,但我相信来源

2 个答案:

答案 0 :(得分:3)

我建议在UNION

中颠倒查询的顺序

这是因为SELECT中的第一个UNION确定了结果集中列的数据类型;在您的情况下,UNION的第一列采用questionario_punteggi.xd列的类型:即CHAR(3) NOT NULL

由于您在UNION的第一部分上应用了聚合函数,因此即使 没有记录与过滤条件匹配,也会产生单行。正如GROUP BY (Aggregate) Functions所述:

  如果没有匹配的行,

AVG()会返回NULL

hidden xd列的值通常是与过滤器匹配的不确定选择的记录(这就是为什么你可能不想这样做);但是,由于在这种情况下没有匹配的记录,服务器会返回NULL(显然不能进入具有NOT NULL属性的列。)

通过颠倒UNION的顺序,该列将不具有NOT NULL属性。您可能需要对列进行适当的别名:

SELECT 1 AS xd, 2 AS avg_media
UNION
SELECT xd, AVG(media) FROM questionario_punteggi WHERE somefield = 1

用它来依次解释你的每个观察结果:

  •   

    如果删除AVG(),查询将起作用。

    由于不再执行聚合,SELECT中的第一个UNION会产生一个空记录集,因此第一列中没有NULL记录。

  •   

    如果我删除xd(以及右边的1,2中的2),查询将起作用。

    由于不再选择隐藏列,MySQL不再在其位置返回NULL

  •   

    如果删除UNION,查询将起作用。

    这是您的MySQL版本和您的同事之间可能已修复的错误:NOT NULL属性不应该真正适用于UNION结果。

  •   

    如果我用somefield = 1设置一些记录,则查询有效。

    为隐藏列选择的值是匹配记录中不确定的(但非NULL值,由于列的属性)。

  •   

    在另一台机器5.5上查询有效。

    这个错误(我还在搜索它)必须在各自版本的MySQL之间修复。

答案 1 :(得分:2)

尝试使用SELECT IFNULL();

Select IFNULL(xd,0), avg(media) f
rom questionario_punteggi 
where somefield = 1 
union 
select 1,2

http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_ifnull