生成列的值未出现在表中

时间:2012-06-04 17:24:53

标签: mysql mysql-5.1

我正在使用mysql版本5.1.41-3ubuntu12.10 (Ubuntu)

mysql> show create table tt\G
*************************** 1. row ***************************
       Table: tt
Create Table: CREATE TABLE `tt` (
  `pz` int(8) DEFAULT NULL,
  `os` varchar(8) DEFAULT NULL,
  `uz` int(11) NOT NULL,
  `p` bigint(21) NOT NULL DEFAULT '0',
  `c` decimal(23,0) DEFAULT NULL,
  KEY `pz` (`pz`),
  KEY `uz` (`uz`),
  KEY `os` (`os`),
  KEY `pz_2` (`pz`,`uz`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> select pz,uz,pz*uz,
    -> if(pz*uz,1,.5),
    -> left(pz,2) pl,left(lpad(uz,5,0),2) ul,
    -> p from tt limit 10;
+-------+----+-------+----------------+--------+----+--------+
|   pz  | uz | pz*uz | if(pz*uz,1,.5) |   pl   | ul |    p   |
+-------+----+-------+----------------+--------+----+--------+
|  NULL |  0 |  NULL |            0.5 | NULL   | 00 |   4080 |
|  NULL |  0 |  NULL |            0.5 | NULL   | 00 | 323754 |
| 89101 |  0 |     0 |            0.5 | 89     | 00 |   6880 |
|     0 |  0 |     0 |            0.5 | 0      | 00 |  11591 |
| 89110 |  0 |     0 |            0.5 | 89     | 00 |     72 |
| 78247 |  0 |     0 |            0.5 | 78     | 00 |     27 |
| 90062 |  0 |     0 |            0.5 | 90     | 00 |      5 |
| 63107 |  0 |     0 |            0.5 | 63     | 00 |      4 |
|  NULL |  0 |  NULL |            0.5 | NULL   | 00 |  54561 |
| 94102 |  0 |     0 |            0.5 | 94     | 00 |  12499 |
+-------+----+-------+----------------+--------+----+--------+

到目前为止一切顺利。如您所见,0.5显示为if(pz*uz,1,.5)的值。问题是:

mysql> select os,
    -> if(pz*uz,left(pz,2)<=>left(lpad(uz,5,0),2),.5) uptwo,
    -> if(pz*uz,left(pz,3)<=>left(lpad(uz,5,0),3),.5) upthree,
    -> sum(p) p,sum(c) c
    -> from tt t
    -> group by os,uptwo,upthree order by null;

+----+-------+---------+---------+-------+
| os | uptwo | upthree |    p    |   c   |
+----+-------+---------+---------+-------+
| u  |     1 |       1 |   52852 |   318 |
| i  |     1 |       1 | 7046563 | 21716 |
| m  |     1 |       1 | 1252166 |  7337 |
| i  |     0 |       0 | 1830284 |  4033 |
| m  |     0 |       0 |  294612 |  1714 |
| i  |     1 |       0 |  911486 |  3560 |
| m  |     1 |       0 |  145182 |  1136 |
| u  |     0 |       0 |   12144 |    23 |
| u  |     1 |       0 |    1571 |     8 |
+----+-------+---------+---------+-------+

虽然我group by uptwo,但该列中没有出现0.5。 0.5值发生了什么变化?


编辑:正如Todd Gibson's answer的评论中所述,我也尝试过 if(pz*uz,cast(left(pz,2)<=>left(lpad(uz,5,0),2) as decimal),.5)而非 if(pz*uz,left(pz,2)<=>left(lpad(uz,5,0),2),.5),但它也没有用。

3 个答案:

答案 0 :(得分:3)

而不是.5作为IF()的错误条件,请使用0.5

if(pz*uz,left(pz,2)<=>left(lpad(uz,5,0),2),0.5) uptwo

if(pz*uz,left(pz,3)<=>left(lpad(uz,5,0),3),0.5) upthree

我相信发生的事情是在评估GROUP BY之后,条件列中的值必须是相同的数据类型。由于在SELECT之后评估GROUP BYIF()正在转换返回的值,而不是整数(来自布尔表达式),因此您的0.5会向上舍入到1但是如果您在小数位前面明确地放置0,则IF()会将返回值视为小数,包括布尔表达式的结果(即1.00.0)。

或者您甚至可以在.4周围放置单引号,以便将列值视为字符串,因此某些值将显示为整数和一些小数。在数值上下文中使用时,应自动转换这些值(即SELECT ('2.5' * 3.5) AS test #8.75)。

答案 1 :(得分:1)

我认为uptwo和upthree列被隐式转换为整数。在expression2上使用convert()强制它为小数。

答案 2 :(得分:0)

我认为您在以下陈述中遇到问题:

-> if(pz*uz,left(pz,2)<=>left(lpad(uz,5,0),2),.5) uptwo,
-> if(pz*uz,left(pz,3)<=>left(lpad(uz,5,0),3),.5) upthree,

在声明中,pz*uz的值必须始终为greater than or equal to 1 因此,第一个表达式的值用于替换第二个表达式0.5

让我们分析第一个if函数声明:
语法IF(expr1,expr2,expr3)
含义if value of expr1 is >= 1 use expr1 else use expr3
Expression1 pz*uz //此值必须为'>= 1' Expression2 left(pz,2)<=>left(lpad(uz,5,0),2) //此值为'1''0'
Expression3 .5