这个SQL怎么改啊?在线等待!

wjmsino 2003-08-22 04:14:03
SELECT sum(nvl(a.retail_money,0)),sum(nvl(a.trade_price,0)*nvl(a.amount,0)*nvl(a.account,0)),sum(nvl(a.balance_money,0))
FROM t_ps_arrive_attached a , t_ps_arrive_main b ,t_ps_duginf c
WHERE a.in_no = b.in_no
AND a.affirm_date >= :ld_start
AND a.affirm_date <= :ld_end
AND a.drug_no = c.drug_no
AND b.businessman like :ls_code_factory
AND c.drug_kind = :ls_code
AND a.status = '1'
AND (a.save_status = '' or a.save_status is null);
a,b是主从表,in_no是主表关键字,当主表数据对应从表多条记录查询有问题。
别外两个表数据量也比较大,速度也要考虑一下。
各位高手这个怎么改?
...全文
38 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
wzhwzh100 2003-08-22
  • 打赏
  • 举报
回复
SELECT sum(nvl(a.retail_money,0)),sum(nvl(a.trade_price,0)*nvl(a.amount,0)*nvl(a.account,0)),sum(nvl(a.balance_money,0))
FROM t_ps_arrive_attached a
WHERE a.affirm_date >= :ld_start
AND a.affirm_date <= :ld_end
AND a.status = '1'
AND (a.save_status = '' or a.save_status is null)
AND EXISTS (SELECT 'DATA' FROM t_ps_arrive_main b WHERE b.in_no=a.in_no AND b.businessman LIKE :ls_code_factory)
AND EXISTS (SELECT 'DATA' FROM t_ps_duginf c WHERE a.drug_no = c.drug_no AND c.drug_kind = :ls_code);
beckhambobo 2003-08-22
  • 打赏
  • 举报
回复
转贴:
1.ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.

例如:

表 TAB1 16,384 条记录

表 TAB2 1 条记录

选择TAB2作为基础表 (最好的方法)

select count(*) from tab1,tab2 执行时间0.96秒

选择TAB2作为基础表 (不佳的方法)

select count(*) from tab2,tab1 执行时间26.09秒

如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.



例如:


EMP表描述了LOCATION表和CATEGORY表的交集.


SELECT *

FROM LOCATION L ,

CATEGORY C,

EMP E

WHERE E.EMP_NO BETWEEN 1000 AND 2000

AND E.CAT_NO = C.CAT_NO

AND E.LOCN = L.LOCN



将比下列SQL更有效率



SELECT *

FROM EMP E ,

LOCATION L ,

CATEGORY C

WHERE E.CAT_NO = C.CAT_NO

AND E.LOCN = L.LOCN

AND E.EMP_NO BETWEEN 1000 AND 2000



2.WHERE子句中的连接顺序.

ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.



例如:



(低效,执行时间156.3秒)

SELECT …

FROM EMP E

WHERE SAL > 50000

AND JOB = ‘MANAGER’

AND 25 < (SELECT COUNT(*) FROM EMP

WHERE MGR=E.EMPNO);



(高效,执行时间10.6秒)

SELECT …

FROM EMP E

WHERE 25 < (SELECT COUNT(*) FROM EMP

WHERE MGR=E.EMPNO)

AND SAL > 50000

AND JOB = ‘MANAGER’;
wjmsino 2003-08-22
  • 打赏
  • 举报
回复
我的目地是只要汇总的值。
a.in_no = b.in_no
我想问一下,在这种查询情况下他的一对多到底有没有影响,
在select的时候是按多条记录显示吧。那么sum()也不会出错吧。

BlueskyWide(谈趣者)大哥:
那样的顺序是什么道理,能说说吗?
hot.wind 2003-08-22
  • 打赏
  • 举报
回复
你的查询的目的是什么?只得到一条记录还是分组合计的记录?从你上面的查询结果看,可能会返回多条记录。问题主要在
WHERE a.in_no = b.in_no
这个约束上。如果哦a与b是一对多的关系,结果可能是错误的。
BlueskyWide 2003-08-22
  • 打赏
  • 举报
回复
修改次序试一下:
SELECT sum(nvl(a.retail_money,0)),sum(nvl(a.trade_price,0)*nvl(a.amount,0)*nvl(a.account,0)),sum(nvl(a.balance_money,0))
FROM t_ps_arrive_attached a,t_ps_arrive_main b,t_ps_duginf c
WHERE a.in_no = b.in_no
AND a.drug_no = c.drug_no
AND c.drug_kind = :ls_code
AND a.status = '1'
AND (a.save_status = '' or a.save_status is null)
AND b.businessman like :ls_code_factory
AND a.affirm_date >= :ld_start
AND a.affirm_date <= :ld_end;

17,078

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧