我正在使用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)
,但它也没有用。
答案 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 BY
,IF()
正在转换返回的值,而不是整数(来自布尔表达式),因此您的0.5
会向上舍入到1
但是如果您在小数位前面明确地放置0
,则IF()
会将返回值视为小数,包括布尔表达式的结果(即1.0
或0.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