求一个等价query

[复制链接]
查看11 | 回复6 | 2010-3-1 11:04:59 | 显示全部楼层 |阅读模式
本帖最后由 KEN6503 于 2018-4-24 09:04 编辑
下面第一个query (红颜色) 是原来的query, 第二个是我改写的query, 我觉得这两个应该是等价的,但是结果不等,麻烦大师帮忙看看。我漏掉什么条件了我的理解是:蓝色query 是得到在表BGL中而不在表BMT中的记录;紫色的query是表BMT中符合条件BMT.FLAG >= '4' OR BMT.FLAG IS NULL记录与表BGL作inner join。 所以,合在一起就是:BGL 与BMT中符合条件BMT.FLAG >= '4' OR BMT.FLAG IS NULL的记录作left outer join。 但是,结果不对。写成紫红色的query, 结果是对的。
SELECTSUM (CNT), SUM (AMT)
FROM (SELECT COUNT (1) CNT, SUM (ABS (BGL.BGL_AMN)) AMT

FROMBMT,BGL
WHERE BGL.PT_NMBR = BMT.PT_NMBR(+)

AND BMT.PT_NMBR IS NULL
UNION ALL

SELECT COUNT (1) CNT, SUM (ABS (BGL.BGL_AMN))

FROMBMT,BGL
WHERE BGL.PT_NMBR = BMT.PT_NMBR

AND (BMT.FLAG >= '4' OR BMT.FLAG IS NULL));

SELECT COUNT (1) CNT, SUM (ABS (BGL.BGL_AMN))
FROM (SELECT *

FROMBMT
WHERE BMT.FLAG >= '4' OR BMT.BMT.FLAG IS NULL) BMT_O,
BGL
WHERE BGL.PT_NMBR = BMT_O.PT_NMBR(+);
SELECT COUNT (1) CNT, SUM (ABS (BGL.BGL_AMN))
FROM BMT, BGL
WHEREBGL.PT_NMBR = BMT_O.PT_NMBR(+)
AND ((BMT.FLAG >= '4'
OR BMT.BMT.FLAG IS NULL) OR BMT.PT_NMBR IS NULL);




回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
给出建表脚本及结果
回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
差太多了
第一个是 AND (PT_NMBR IS NULL OR (PT_NMBR IS NOT NULL AND (FLAG >= '4' OR FLAG IS NULL)))
第二个是 AND 1 = 1
回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
你在这混了有阵子了吧?知道我的口头禅是什么?为什么要浪费别人时间?
你这个原查询根本都解析不了。 AND PT_NMBR IS NULL,这个列两边都有的。
回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
newkid 发表于 2018-4-23 21:37
你在这混了有阵子了吧?知道我的口头禅是什么?为什么要浪费别人时间?
你这个原查询根本都解析不了。 AND ...

谢谢提醒
我把要求重写了。麻烦你看一下。
回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
置顶帖提问的智慧要求给出数据结构以及测试用例。
就你的写法来看,可以猜出BMT.PT_NMBR是唯一的。
但是你为什么要让人猜呢?别人的时间不宝贵?
你对原查询红色和紫色的理解是对的,但是“合在一起”就毫无逻辑,不知道这个结论怎么跳出来的。蓝色部分在你的黑色改写中怎么体现?原来要算的是“连接不上”的那些数据,结果你搞了个外连接,相当于是无条件地、所有BGL的数据全部计算。
回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
本帖最后由 KEN6503 于 2018-4-24 11:16 编辑
newkid 发表于 2018-4-24 09:14
置顶帖提问的智慧要求给出数据结构以及测试用例。
就你的写法来看,可以猜出BMT.PT_NMBR是唯一的。
但是 ...

谢谢指正。今后一定注意。
我认为这两个query是等价的。

现在明白了。


SELECT COUNT (1) CNT, SUM (ABS (BGL.BGL_AMN))
FROM (SELECT *

FROMBMT
WHERE BMT.FLAG >= '4' OR BMT.BMT.FLAG IS NULL) BMT_O,
BGL
WHERE BGL.PT_NMBR = BMT_O.PT_NMBR(+);
SELECT COUNT (1) CNT, SUM (ABS (BGL.BGL_AMN))
FROM BMT, BGL
WHEREBGL.PT_NMBR = BMT_O.PT_NMBR(+)
AND ((BMT.FLAG >= '4'
OR BMT.BMT.FLAG IS NULL) OR BMT.PT_NMBR IS NULL);
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行