PostgreSQL查询结果错误一例
来源:互联网 发布:淘宝和京东的相同点 编辑:程序博客网 时间:2024/06/10 02:01
CREATE TABLE t1 (a int, b int);
CREATE TABLE t2 (c int, d int);
CREATE TABLE t3 (e int);
INSERT INTO t1 VALUES
(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
INSERT INTO t2 VALUES
(2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
INSERT INTO t3 VALUES (10), (30), (10), (20) ;
二 PostgreSQL 版本
test=# select version();
version
-------------------------------------------------------------
PostgreSQL 9.3.4, compiled by Visual C++ build 1700, 64-bit
(1 row)
三 执行查询(按SQL的语义,应该得到的结果是a列值为1和2,没有3和4)
test=# SELECT t1.a FROM t1
test-# GROUP BY t1.a
test-# HAVING t1.a < ALL(
test(# SELECT t2.c FROM t2
test(# GROUP BY t2.c
test(# HAVING EXISTS(
test(# SELECT t3.e FROM t3
test(# GROUP BY t3.e
test(# HAVING SUM(t1.a+t2.c) < t3.e/4));
a
---
4
1
3
2
(4 rows)
四 查看查询执行计划
test=# EXPLAIN
test-# SELECT t1.a FROM t1
test-# GROUP BY t1.a
test-# HAVING t1.a < ALL(
test(# SELECT t2.c FROM t2
test(# GROUP BY t2.c
test(# HAVING EXISTS(
test(# SELECT t3.e FROM t3
test(# GROUP BY t3.e
test(# HAVING SUM(t1.a+t2.c) < t3.e/4));
QUERY PLAN
---------------------------------------------------------------------------
HashAggregate (cost=36.75..969979.25 rows=200 width=4)
Filter: (SubPlan 2)
-> Seq Scan on t1 (cost=0.00..31.40 rows=2140 width=4)
SubPlan 2
-> HashAggregate (cost=47.45..9651.45 rows=200 width=4)
Filter: (SubPlan 1)
-> Seq Scan on t2 (cost=0.00..31.40 rows=2140 width=4)
SubPlan 1
-> HashAggregate (cost=48.00..48.67 rows=67 width=4)
-> Seq Scan on t3 (cost=0.00..46.00 rows=800 width=4)
Filter: (sum((t1.a + t2.c)) < (e / 4))
(11 rows)
五 MySQL的执行结果
mysql> SELECT t1.a FROM t1
-> GROUP BY t1.a
-> HAVING t1.a < ALL(
-> SELECT t2.c FROM t2
-> GROUP BY t2.c
-> HAVING EXISTS(
-> SELECT t3.e FROM t3
-> GROUP BY t3.e
-> HAVING SUM(t1.a+t2.c) < t3.e/4));
+------+
| a |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.01 sec)
================
附记: 有朋友联系我说:
PostgreSQL查询结果错误一例 HAVING SUM(t1.a+t2.c) < t3.e/4)); postgres 和mysql在 除法操作 / 处理不一样, 如果都是int,pg会截断;而mysql不会; select 10/4; 和 select 10/4.0 结果不一样
这话确实对. 所以进一步解释如下(PostgreSQL 1到3例, 4例是MySQL):
(1)把t3.e/4变为t3.e/4.0,这样,后者比前者更大一些(更容易使得条件满足),但是得到的结果是:a为1和2
test=# SELECT t1.a FROM t1
test-# GROUP BY t1.a
test-# HAVING t1.a < ALL(
test(# SELECT t2.c FROM t2
test(# GROUP BY t2.c
test(# HAVING EXISTS(
test(# SELECT t3.e FROM t3
test(# GROUP BY t3.e
test(# HAVING SUM(t1.a+t2.c) < t3.e/4.0));
a
---
1
2
(2 rows)
(2) 而 SUM(t1.a+t2.c) < t3.e/4<t3.e/4.0 , 结果得到a列值为4,1,3,2; 这显然不对(对比上例).
test=# SELECT t1.a FROM t1
test-# GROUP BY t1.a
test-# HAVING t1.a < ALL(
test(# SELECT t2.c FROM t2
test(# GROUP BY t2.c
test(# HAVING EXISTS(
test(# SELECT t3.e FROM t3
test(# GROUP BY t3.e
test(# HAVING SUM(t1.a+t2.c) < t3.e/4));
a
---
4
1
3
2
(4 rows)
(3) 验证t3.e/4, t3.e/4.0的大小关系
test=# select t3.e/4, t3.e/4.0 from t3;
?column? | ?column?
----------+--------------------
2 | 2.5000000000000000
7 | 7.5000000000000000
2 | 2.5000000000000000
5 | 5.0000000000000000
(4 rows)
(4) MySQL一例
mysql> select 10/4, 10/4.0;
+--------+--------+
| 10/4 | 10/4.0 |
+--------+--------+
| 2.5000 | 2.5000 |
+--------+--------+
1 row in set (0.00 sec)
- PostgreSQL查询结果错误一例
- postgresql 查询结果 多行变一行
- Postgresql 将SQL 查询结果写入文件
- PostgreSQL JDBC:查询和处理结果
- PostgreSQL将查询结果输出到新表
- Postgresql将查询结果导出Shapefile文件
- PostgreSQL:bytea字段读取结果错误
- Postgresql将查询结果导出到文件中
- PostgreSQL查询代价估算(一)
- Postgresql 触发器一例
- Postgresql 恢复一例
- JPA 本地查询,结果数据获取错误
- PostgreSQL查询优化:查询条件优化一(条件分类)
- postgresql查询
- PostgreSQL中主键索引为什么不能被查询利用到?---索引使用情况一例
- PostgreSQL查询优化一例---使用CTE优化,兼谈松散扫描
- PostgreSQL PARSE等待一例
- PostgreSQL源码修改 ——查询优化(一)
- 子查询辨析
- PPTP协议工作原理
- 简谈子查询的优化---与达梦公司@joehan100先生探讨
- MySQL是怎么使用索引条件下推的?
- MySQL的ORDERBY...LIMIT优化思路
- PostgreSQL查询结果错误一例
- (原创)我对未来的人类的发展,以及AI技术发展的一些思考。
- 利用android studio实现手机信息界面
- 开源数据库PostreSQL与MySQL,未来数据处理的新选择
- 重新开始写blog
- PostgreSQL查询优化一例---使用CTE优化,兼谈松散扫描
- where do I turn?
- Is Query Optimization a “Solved” Problem?
- PostgreSQL-XL, PostgreSQL集群项目