3

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

我们是两个开发人员,都拥有相同的 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 之前已修复。我没有详细信息,但我相信消息来源

4

2 回答 2

3

我建议颠倒UNION.

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

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

AVG()NULL如果没有匹配的行则返回。

隐藏 列的值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 之间修复。

于 2013-01-18T15:49:38.120 回答
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

于 2013-01-18T15:29:22.420 回答