【发布时间】:2019-03-01 01:48:32
【问题描述】:
我执行了第一个查询,但没有得到预期的结果。然后我意识到1 slope 被解释为整数,因此t.slope*pchp.sign*p.slope slope, t.intercept+t.slope*pchp.sign*p.intercept intercept 中的t.slope 也充当整数。
然后我重复了查询,但这次将slope 和intercept 都转换为小数,并获得了正确的结果。
然后我又重复了第二次查询,但只对值不为零但不是intercept的slope进行了一次转换,也得到了正确的结果。
这引出了我的问题。什么时候需要类型转换 SQL 列?
MariaDB [testing]> WITH RECURSIVE t AS (
-> SELECT id, id pointsId, type, 0 value, 0 prevValue, 1 slope, 0 intercept
-> FROM points
-> WHERE id IN (406, 428)
-> UNION ALL
-> SELECT t.id, pchp.pointsId, p.type, p.value, p.prevValue, t.slope*pchp.sign*p.slope slope, t.intercept+t.slope*pchp.sign*p.intercept intercept
-> FROM t
-> INNER JOIN points_custom_has_points pchp ON pchp.pointsCustomId=t.pointsId
-> INNER JOIN points p ON p.id=pchp.pointsId
-> )
-> SELECT id, SUM(slope*value+intercept) value, SUM(slope*prevValue+intercept) prevValue FROM t WHERE type='real' GROUP BY id;
+-----+--------+-----------+
| id | value | prevValue |
+-----+--------+-----------+
| 406 | 0 | 0 |
| 428 | 123702 | 123702 |
+-----+--------+-----------+
2 rows in set (0.00 sec)
MariaDB [testing]> WITH RECURSIVE t AS (
-> SELECT id, id pointsId, type, 0 value, 0 prevValue, CAST(1 AS DECIMAL(12,4)) slope, CAST(0 AS DECIMAL(12,4)) intercept
-> FROM points
-> WHERE id IN (406, 428)
-> UNION ALL
-> SELECT t.id, pchp.pointsId, p.type, p.value, p.prevValue, t.slope*pchp.sign*p.slope slope, t.intercept+t.slope*pchp.sign*p.intercept intercept
-> FROM t
-> INNER JOIN points_custom_has_points pchp ON pchp.pointsCustomId=t.pointsId
-> INNER JOIN points p ON p.id=pchp.pointsId
-> )
-> SELECT id, SUM(slope*value+intercept) value, SUM(slope*prevValue+intercept) prevValue FROM t WHERE type='real' GROUP BY id;
+-----+-------------+-------------+
| id | value | prevValue |
+-----+-------------+-------------+
| 406 | 49480.8000 | 49480.8000 |
| 428 | 123702.0000 | 123702.0000 |
+-----+-------------+-------------+
2 rows in set (0.00 sec)
MariaDB [testing]> WITH RECURSIVE t AS (
-> SELECT id, id pointsId, type, 0 value, 0 prevValue, CAST(1 AS DECIMAL(12,4)) slope, 0 intercept
-> FROM points
-> WHERE id IN (406, 428)
-> UNION ALL
-> SELECT t.id, pchp.pointsId, p.type, p.value, p.prevValue, t.slope*pchp.sign*p.slope slope, t.intercept+t.slope*pchp.sign*p.intercept intercept
-> FROM t
-> INNER JOIN points_custom_has_points pchp ON pchp.pointsCustomId=t.pointsId
-> INNER JOIN points p ON p.id=pchp.pointsId
-> )
-> SELECT id, SUM(slope*value+intercept) value, SUM(slope*prevValue+intercept) prevValue FROM t WHERE type='real' GROUP BY id;
+-----+-------------+-------------+
| id | value | prevValue |
+-----+-------------+-------------+
| 406 | 49480.8000 | 49480.8000 |
| 428 | 123702.0000 | 123702.0000 |
+-----+-------------+-------------+
2 rows in set (0.00 sec)
MariaDB [testing]>
表定义如下:
MariaDB [testing]> explain points;
+----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| idPublic | int(11) | NO | MUL | 0 | |
| accountsId | int(11) | NO | MUL | NULL | |
| name | varchar(45) | NO | MUL | NULL | |
| value | float | YES | | NULL | |
| prevValue | float | YES | | NULL | |
| units | varchar(45) | YES | | NULL | |
| type | char(8) | NO | MUL | NULL | |
| slope | float | NO | | 1 | |
| intercept | float | NO | | 0 | |
| tsValueUpdated | datetime | YES | | NULL | |
| sourceTypeId | tinyint(4) | YES | MUL | NULL | |
+----------------+-------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)
MariaDB [testing]> explain points_custom_has_points;
+----------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------+------+-----+---------+-------+
| pointsCustomId | int(11) | NO | PRI | NULL | |
| pointsId | int(11) | NO | PRI | NULL | |
| sign | tinyint(4) | NO | MUL | 1 | |
+----------------+------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
MariaDB [testing]>
【问题讨论】:
-
很高兴看到一些(简洁的)表定义。一般来说,你应该总是在必要时进行强制转换,事实上许多其他数据库在这方面比 MySQL/MariaDB 严格得多。
-
@TimBiegeleisen 添加了定义。是的,我认为我应该总是在必要时这样做:) 但是什么时候有必要呢?您关于其他数据库更严格的评论使我相信我应该始终这样做,除非列数据类型由表定义规定,并且我也应该将
0类型转换为整数,即使它不这样做也可以工作。 -
嗯,
sign tinyint(4)会引起问题吗?