SQL语法高手请帮我解决一个难题? ( 积分: 200 )

  • 主题发起人 主题发起人 dadada
  • 开始时间 开始时间
D

dadada

Unregistered / Unconfirmed
GUEST, unregistred user!
with&nbsp;ADOQuery1&nbsp;do<br>begin<br>close;<br>sql.clear;<br>sql.add('&nbsp;Select&nbsp;a.clbh,a.clname,a.gg,&nbsp;');<br>//#1计算数量开始<br>sql.add('&nbsp;(select&nbsp;sum(b.sl)&nbsp;from&nbsp;入库表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)&nbsp;As&nbsp;入库总量,&nbsp;');<br>sql.add('&nbsp;(select&nbsp;sum(b.sl)&nbsp;from&nbsp;销售表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)&nbsp;As&nbsp;销售总量,&nbsp;');<br>sql.add('&nbsp;(select&nbsp;sum(b.sl)&nbsp;from&nbsp;报废表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)&nbsp;As&nbsp;报废总量,&nbsp;');<br>//#1计算数量结束<br>//#2计算加权平均入库单价开始<br>sql.add('&nbsp;(select&nbsp;sum(b.je)/sum(b.sl)&nbsp;from&nbsp;入库表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)&nbsp;As&nbsp;单价,&nbsp;');<br>//#2计算加权平均入库单价结束&nbsp;<br>//#3计算金额开始<br>sql.add('&nbsp;(select&nbsp;sum(b.je)&nbsp;from&nbsp;入库表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)&nbsp;As&nbsp;入库总额,&nbsp;');<br>sql.add('&nbsp;(select&nbsp;sum(b.sl)&nbsp;from&nbsp;销售表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)*&nbsp;');<br>sql.add('&nbsp;(select&nbsp;sum(b.je)/sum(b.sl)&nbsp;from&nbsp;入库表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)&nbsp;As&nbsp;销售成本,&nbsp;<br><br>');&nbsp;//*注意这句,重复引用,不科学*<br>sql.add('&nbsp;(select&nbsp;sum(b.sl)&nbsp;from&nbsp;报废表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)*&nbsp;');<br>sql.add('&nbsp;(select&nbsp;sum(b.je)/sum(b.sl)&nbsp;from&nbsp;入库表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)&nbsp;As&nbsp;报废成本,&nbsp;<br><br>');&nbsp;//*注意这句,重复引用,不科学*<br>//#3计算金额结束<br>//#4计算库存开始<br>...省略了,加加减减,大家明白就行了,代码太长<br>//#4计算库存结束<br>sql.add('&nbsp;from&nbsp;商品档案表&nbsp;a&nbsp;');<br>open;<br>end;<br>***************************<br>好了,这是一个计算进销存的SQL语句,我写出来的是一个经过简化的例子,实际应用中,还要加上期间<br><br>判断等等条件,因此代码十分的长,长到showmessage(sql.text)时整个屏幕都显示不完.<br>我遇到的问题是:这段代码如果写在客户端,在有些机子就会出现&quot;系统内存不足运行此查询!&quot;<br>我把它改成存储过程,运行的速度也相当的慢.<br>假设仍使用本语句来计算,有没有改良的方法呢,有,我认为问题就出在后面算&quot;各种出库的成本时&quot;,<br><br>每次都要原封原样的引用&quot;算加权单价&quot;那段代码,不但造成整个SQL语句的代码超长,而且肯定就是耗<br><br>费内存的祸首!<br>我要想改的地方,就是那个加权单价的引用方式,因为在实际项目中,我的计算加权平均单价的代码有<br><br>10行那么长的,按照我上面的写法,就会造成:算销售成本时copy它,算报废成本时copy它,等等,中间<br><br>凡是要用到这个单价的地方,都要在SQL语句里copy一次,最后算结存金额时,还要copy一次,于是整条<br><br>SQL语句就变得好长啊!运行起来就出现内存不足.<br>说了这么多,读帖的朋友都应该弄清楚我的问题了吧?<br>请高手支招,帮我改良写法,或者提供更有效率的算法?
 
你这样写的语句是最慢的!<br>还是想想建临时表吧!<br>不建的话也要优化,增加速度的空间太大了!
 
建议:你可以把这些SQL语句写在一个字串sql中,然后优化下语句,效力可能会提高不少...
 
谢谢楼上两位的关注!<br>To:迷途的羔羊<br>我就是在求助&quot;优化的写法&quot;,但我不主张建临时表,因为建很多个临时表再汇总,不是SQL技术角度的解决方法.<br>我的写法实际是要写到存储过程的,只是为了方便大家分析,才写成这样的,把它转到存储过程里,如果写法还是我这样写,速度仍然慢,感觉问题就出在算成本时,要重算引用那个计算加权单价的代码,如果能够实现只引用一次,整个效率就提高到理想程度!<br>To:nylx<br>把这些语句写在字串中?不就等于写一个存储过程吗,没用的,关键是要改良我的算法,请再支招!
 
使用存储过程,使用临时表,在存储过程中,将你的那么多个次表的数据查询结果写入临时表,这样再查询的话,速度绝对快.<br>我以前以喜欢用嵌套语句,但是在不同的电脑上容易造成超时或者其他的错误,我改回昨时表后,结果好很多.
 
To:L.Ming<br>我就想知道,在嵌套语句里,如何解决那个&quot;计算单价的代码重复引用&quot;,减少计算量和代码长度,这是这个核心的问题,属于SQL语句技法一类的,我想请教的是这方面的,不是如何避免超时,也不想通过临时表解决.<br>这是个典型的进销存计算的例子,虽然参与计算的次表有很多,但我认为这是最清楚的算法了,因为我如果不去算那个成本单价和金额的话,计算速度非常快的!<br>问题就出在&quot;同一个加权单价的计算代码,在一句SQL.TEXT中需要重复引用多次&quot;,有什么写法可以不用多次引用它吗?
 
再详细列出我的问题所在:<br>以下是要改良的语句:<br>select&nbsp;x1,x2,x2/x1&nbsp;as&nbsp;y1,w1*(x2/x1)&nbsp;as&nbsp;x3,w2*(x2/x1)&nbsp;as&nbsp;x4&nbsp;from&nbsp;表名<br>我想改成类似以下的语句:<br>select&nbsp;x1,x2,x2/x1&nbsp;as&nbsp;y1,w1*y1&nbsp;as&nbsp;x3,w2*y1&nbsp;as&nbsp;x4&nbsp;from&nbsp;表名<br>.....<br>好了,各位看明白没有?&nbsp;那个x2/x1就是一个计算,我用y1表示,在同一条语句里,后面的计算如果要引用它,我不得不每次都*(x2/x1),这样造成的问题太多了,内存不足、超时等等。<br>我想改成第二种类似写法,但经实践又行不通?
 
太长,没时间看;
 
就是比较复杂,所以才来请高手指教.<br>但是我已经写得很明白,不要觉得多而被吓倒了.<br>.....<br>请分析以下问题即可:<br>以下是要改良的语句:<br>select&nbsp;x1,x2,x2/x1&nbsp;as&nbsp;y1,w1*(x2/x1)&nbsp;as&nbsp;x3,w2*(x2/x1)&nbsp;as&nbsp;x4&nbsp;from&nbsp;表名<br>我想改成类似以下的语句:<br>select&nbsp;x1,x2,x2/x1&nbsp;as&nbsp;y1,w1*y1&nbsp;as&nbsp;x3,w2*y1&nbsp;as&nbsp;x4&nbsp;from&nbsp;表名<br>.....<br>好了,各位看明白没有?&nbsp;那个x2/x1就是一个计算,我用y1表示,在同一条语句里,后面的计算如果要引用它,我不得不每次都*(x2/x1),这样造成的问题太多了,内存不足、超时等等。<br>我想改成第二种类似写法,但经实践又行不通?
 
既然&nbsp;x2/x1&nbsp;使用极为频繁&nbsp;不知可否考虑&nbsp;在表中增加一字段&nbsp;表里增加数据时直接把该值计算出保存到该字段,&nbsp;这样后面使用时应该提高不少效率吧
 
To:themars<br>x2/x1&nbsp;是一个临时计算字段,且计算的方式是不固定的.再说这里的x2/x1只是举的例子,它代表了需要临时计算的那种&quot;应用需求&quot;,所以不能事先在表中建立固定字段.<br>......<br>等待更多高手发表观点,或提供新思路!
 
写成第二种方式怎么会行不通呢?<br>select&nbsp;x1,x2,&nbsp;y1,w1*y1&nbsp;as&nbsp;x3,w2*y1&nbsp;as&nbsp;x4&nbsp;from&nbsp;表名&nbsp;a,(select&nbsp;x2/x1&nbsp;as&nbsp;y1&nbsp;from&nbsp;tablename)&nbsp;b&nbsp;where&nbsp;a.key=b.key<br>LZ&nbsp;注意现在将所有的表关联起来,用有效条件剔出无用数据,之后再做计算,可以参考一下SQL运行效率方面的资料
 
“我就是在求助&quot;优化的写法&quot;,但我不主张建临时表,因为建很多个临时表再汇总,不是SQL技术角度的解决方法.”<br>菜鸟才会喜欢用一个SQL解决所有查询,你这样的问题很明显需要临时表才能优化<br>还有,你第一个贴里面<br>&nbsp;Select&nbsp;a.clbh,a.clname,a.gg,<br>(select&nbsp;sum(b.sl)&nbsp;from&nbsp;入库表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)&nbsp;As&nbsp;入库总量,<br>(select&nbsp;sum(b.sl)&nbsp;from&nbsp;销售表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)&nbsp;As&nbsp;销售总量,<br>(select&nbsp;sum(b.sl)&nbsp;from&nbsp;报废表&nbsp;b&nbsp;where&nbsp;b.clbh=a.clbh)&nbsp;As&nbsp;报废总量,&nbsp;<br>...<br>这样的写法也我想也是菜鸟菜鸟写出来<br>下面才是常规的写法,虽然我完全肯定是否效率有差别,但是我起码可以说,后面绝对不会比前面慢,也清晰的多。<br>&nbsp;Select&nbsp;a.clbh,a.clname,a.gg,<br>sum(b.sl)&nbsp;As&nbsp;入库总量,<br>sum(b.sl)&nbsp;As&nbsp;销售总量,<br>sum(b.sl)&nbsp;As&nbsp;报废总量,&nbsp;<br>...<br>FROM&nbsp;&nbsp;商品档案表&nbsp;a,入库表&nbsp;b,销售表&nbsp;c,报废表&nbsp;d...<br>WHERE&nbsp;b.clbh=a.clbh&nbsp;AND&nbsp;c.clbh=a.clbh&nbsp;AND&nbsp;d.clbh=a.clbh...<br>再说一个,如果表名都是中文的,不是菜鸟都难。。。
 
好强..偶见到那么长的..头..就晕..哈哈.
 
写成一个字符串,然后用SQL语句优化软件优化一下
 
To:phoebe<br>谢谢你的提示,有画龙点睛之效,我要的可能就是你这种写法,但尚未求证,稍后验证!<br>To:JamesBond_L<br>JamesBond_L你长眼睛没有,我开帖不是说了吗,我开帖写的代码是一个简化的例子,是为了大家在最短时间看个明白,所以用中文表名来代表&quot;表&quot;,还真被你当作菜鸟呢!没关系,可能在你面前,我就是只菜鸟,但你这种口气对待人,不但没有显示你有多高明,只会让人鄙视你!<br>To:shunzi1220<br>谢谢你的建议,有机会我会测试<br>To:other<br>谢谢每一个参与此帖的朋友!<br>还有其他建议的高手可以继续发表,本人下午六点结帖散分.
 
我说这个就预了你给你说的了,可能话的确有点不好听了。。。<br>表的关联都不太会,我的确认为要好好补课了。。。<br>而且我看了很多新人不喜欢临时表,好像临时表得罪了他们似的。。。临时表既可以加快速度,又可以清晰过程,完全没有理由必要时不采用,当然要用也尽量排程大数据量的操作。
 
To:JamesBond_L<br>你这样说,倒有几分风度了,我原谅你了.<br>可能是人的水平问题吧,我一直以为&quot;能用一句sql.text搞定最复杂应用统计的写法才是SQL语法高手&quot;,所以一直追求&quot;一句搞定&quot;,建临时表呀,视图什么的都被认为是转弯抹角的笨办法.<br>昨天听你说了一句&quot;菜鸟才会喜欢用一个SQL解决所有查询&quot;,挺纳闷的.<br>我见过一个比我更菜的鸟,为了实现我这种类似的查询,就在数据库里建了很多个固定的表,然后...你现在说的建很多个临时表,与他的做法有什么本质的区别呢?用得着象这么干吗?<br>一句SQL嵌套语句就能搞定的事,干嘛要整得你那么繁琐呢?<br>除了消耗内存少一些,能提高一点速度,我就想不通你主张临时表的意义了.<br>欢迎说出高见,我看需要补课的人不止我一个呢.
 
“我见过一个比我更菜的鸟,为了实现我这种类似的查询,就在数据库里建了很多个固定的表,然后...你现在说的建很多个临时表,与他的做法有什么本质的区别呢?用得着象这么干吗?<br>”<br>临时表与固定的表是有本质区别的,很好用的<br>正如JamesBond_L&nbsp;所说&nbsp;&quot;临时表既可以加快速度,又可以清晰过程&quot;<br>我觉得&nbsp;如果是比较简单的嵌套&nbsp;可以用一句搞定<br>嵌套的太多很多弊端就出来了,诸如调试,效率等等
 
冲你这原谅,我该再跟你说不好意思~~<br>我一直以为&quot;能用一句sql.text搞定最复杂应用统计的写法才是SQL语法高手&quot;,所以一直追求&quot;一句搞定&quot;,建临时表呀,视图什么的都被认为是转弯抹角的笨办法.<br>你要好好改变你这样的看法了!!按你这样说的,可见你的经验的确不足。(也许我看错了?)<br>所谓的笨不是代码多就是笨的,简单的举个例子,很多程序员喜欢嵌套N多的代码,这个是非常不适合代码维护的,程序的可维护性是非常重要的一样指标!如VB的IIF函数,很多人可以嵌套2、3个,如:<br>IIF(IIF(x,1,2),2,3)<br>其实如果你觉得这样聪明就大错特错了,这样恰恰是笨的表现,懒的表现。也许你经验丰富了,你就知道什么原因了。<br>当然如果一句合适的SQL语句可以解决,没有必要分的,这个合适是很关键的。<br>如果你嵌套N多语句,临时表造成的IO消耗绝对很多时候是比那个要轻的!
 
后退
顶部