首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

sql语句精简有关问题

2012-12-17 
sql语句精简问题,在线等SELECT (SELECT sum(nqhje) FROM t_qhb WHERE CONVERT(datetime,srq,112)BETWEEN d

sql语句精简问题,在线等

SELECT (SELECT sum(nqhje) FROM t_qhb WHERE 
CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND @jk)
/
(SELECT sum(nchje) FROM t_chb WHERE 
CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND @jk) AS 节前15天缺货率
,
(SELECT sum(nqhje) FROM t_qhb WHERE 
CONVERT(datetime,srq,112)BETWEEN @jj AND dateadd(dd,15,@jj))
/
(SELECT sum(nchje) FROM t_chb WHERE 
CONVERT(datetime,srq,112)BETWEEN @jj AND dateadd(dd,15,@jj)) AS 节后15天缺货率
,
(SELECT sum(nqhje) FROM t_qhb WHERE 
CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND dateadd(dd,15,@jj))
/
(SELECT sum(nchje) FROM t_chb WHERE 
CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND dateadd(dd,15,@jj)) AS 前后30天缺货率

t_qhb 缺货表 t _chb 出货表
这段sql好长,条件都重复写了。
 有什么办法能精简下语句吗?
[最优解释]
DECLARE @qk  datetime,@jk datetime 
,@qj  datetime,@jj  datetime 
,@str_jk VARCHAR(10),@str_jj VARCHAR(10)
 
SET @qk='2011-06-21'
SET @jk='2012-06-21'
SET @qj='2011-06-23'
SET @jj='2012-06-22'

SET @str_jk=CONVERT(VARCHAR(10),@jk,120)
SET @str_jj=CONVERT(VARCHAR(10),@jj,120)
  
 DECLARE @WHERE1 NVARCHAR(MAX),@WHERE2 NVARCHAR(MAX),@WHERE3 NVARCHAR(MAX)  
  SELECT @WHERE1='CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,'''+@str_jk+''') AND '''+@str_jk+''''        ,
  @WHERE2='CONVERT(datetime,srq,112) BETWEEN '''+@str_jj+''' AND dateadd(dd,15,'''+@str_jj+''')'        ,
  @WHERE3='CONVERT(datetime,srq,112) BETWEEN dateadd(dd,-15,'''+@str_jk+''') AND dateadd(dd,15,'''+@str_jj+''')

[其他解释]
建议你给出测试数据和表结构   以及你的算法  看看大家写写


光看你的语句  觉得你可以现对这两个表的数据按日期分别汇总  再关联查询处理
[其他解释]
两个表有关联id没?
[其他解释]
(SELECT (SELECT sum(nqhje) FROM t_qhb WHERE CONVERT(datetime,srq,112)BETWEEN @jk AND @jj
AND sspbh NOT IN (SELECT b.GDGID FROM t_ord a,t_orddtl b WHERE a.fildate BETWEEN @jk
AND @jj AND a.num=b.num))
/     
(SELECT sum(nchje) FROM t_chb WHERE CONVERT(datetime,srq,112)BETWEEN @jk AND @jj
AND sspbh NOT IN (SELECT b.GDGID FROM t_ord a,t_orddtl b WHERE a.fildate BETWEEN @jk
AND @jj AND a.num=b.num)) AS 不订货缺货率) g

像这样的感觉where后面都重复了。 能不能联合起来写一次?
[其他解释]
2个表没关联的。就是求相同的时间段内的总金额 然后相除。
 取的条件都一样。就是2个表都要取一次。重复写感觉语句没效率
[其他解释]
语句长不要紧,只要效率不差就行了,对于同一个表,条件并不重复.应该没办法精简.
[其他解释]


谢谢大家。。
现在问题是我有很多这样的句子每条语句都要取这个条件
 程序里面已经超出的字节长度了。必须要精短下。
  有没有什么办法可以把那条件写成一个变量
 然后我每个语句where 后面就直接加个@sql?
[其他解释]
拼接字符串?
[其他解释]
什么办法都行。能实现就可以。现在就是语句太长了。
  

引用:
拼接字符串?

[其他解释]
引用:
什么办法都行。能实现就可以。现在就是语句太长了。
  

引用:拼接字符串?


你给出你的表结构和测试数据  再说说你的算法  我看了你的语句  应该是可以换个写法的
[其他解释]
t_chb  出货表
srq  时间      sspbh   编码    nchsl  数量  nchje  金额
2011060200091251     67.00221.10
2011060201060010     16.00124.80
2011060201090215     60.00378.00
2011060201090239     296.002308.80
2011060201090246     464.001948.80
2011060201090284     924.002698.08
2011060201090321     233.00477.65
t_qhb 去货表 
结构一样。就是最后的金额字段换成nqhje。
我就是求缺货表一段时间内sum(金额)再除以出货表的sum(金额)
可能具体取哪段时间哪些编码。2个表都取的一样的条件。就写2次了。。

引用:
引用:
什么办法都行。能实现就可以。现在就是语句太长了。
  

引用:拼接字符串?

你给出你的表结构和测试数据  再说说你的算法  我看了你的语句  应该是可以换个写法的

[其他解释]
引用:
t_chb  出货表
srq  时间      sspbh   编码    nchsl  数量  nchje  金额
2011060200091251     67.00221.10
2011060201060010     16.00124.80
2011060201090215     60.00378.00
20110602010902……


你这两个表没得关系  汇总时间也不一样  那基本上没法怎么精简了  你的写法也对  我刚刚看成了时间范围是一样的  那样的话就可以精简一下  不好意思
[其他解释]
引用:
引用:
t_chb  出货表
srq  时间      sspbh   编码    nchsl  数量  nchje  金额
20110602 00091251      67.00 221.10
20110602 01060010      16.00 124.80
20110602 01090215      60.00 378.00
201……

不是啊。我汇总时间是一样啊
 2个表都是取一样的时间汇总的
[其他解释]
语句长没法拼?
写成三句不就行了:
1.
SELECT (SELECT sum(nqhje) FROM t_qhb WHERE CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND @jk) / (SELECT sum(nchje) FROM t_chb WHERE CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND @jk) AS 节前15天缺货率

2.
select (SELECT sum(nqhje) FROM t_qhb WHERE CONVERT(datetime,srq,112)BETWEEN @jj AND dateadd(dd,15,@jj)) / (SELECT sum(nchje) FROM t_chb WHERE CONVERT(datetime,srq,112)BETWEEN @jj AND dateadd(dd,15,@jj)) AS 节后15天缺货率



3.
select (SELECT sum(nqhje) FROM t_qhb WHERE CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND dateadd(dd,15,@jj)) / (SELECT sum(nchje) FROM t_chb WHERE CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND dateadd(dd,15,@jj)) AS 前后30天缺货率 
[其他解释]
发帖的这个例子可能不太清楚。
  你可以看下3楼的例子。应该能说明我的问题和需求
[其他解释]
更简便的方法,是用6个语句,分别从数据库里求出统计值,然后在你的程序里去求除法.

兄弟,要学会变通.
[其他解释]

引用:
语句长没法拼?
写成三句不就行了:
1.
SELECT (SELECT sum(nqhje) FROM t_qhb WHERE CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND @jk) / (SELECT sum(nchje) FROM t_chb WHERE CONVERT(datetime,srq,112)BETWEEN ……

不是的。。
   我是把这些结果放进一个select里面。分成3句单独看是短了。但是都得放进程序里面去的。
程序sql字符就超出了。所以希望把每天重复写的条件语句能不能整合起来?或者用一个什么变量代替也行?
[其他解释]
引用:
更简便的方法,是用6个语句,分别从数据库里求出统计值,然后在你的程序里去求除法.

兄弟,要学会变通.

呵呵 。谢谢我以后会注意。
  不过现在我是用sql做万能报表 只能用一个select查出这些数据
但是他的报表有sql字数限制。写太长就不行啊
[其他解释]
那,另外建三个函数,计算相应的东西并返回,然后在语句中调用这个函数就行了.
[其他解释]
SELECT sum(b.arvqty*b.price)/sum(b.qty*b.price)  节前后30天订单满足率,
 sum(CASE WHEN a.fildate>@jk THEN 0 ELSE b.arvqty END*b.price)/sum
 (CASE WHEN a.fildate>@jk THEN 1 ELSE b.qty END*b.price)  节前15天订单满足率
 ,sum(CASE WHEN a.fildate<@jj THEN 0 ELSE b.arvqty END*b.price)/sum
 (CASE WHEN a.fildate<@jj THEN 1 ELSE b.qty END*b.price)  节后15天订单满足率 FROM t_ord a,t_orddtl b
 WHERE a.fildate BETWEEN dateadd(dd,-15,@jk)  AND  dateadd(dd,15,@jj)
 AND a.num=b.NUM 

像这样的就可以只写一次条件,
 但是像发帖例子那样涉及到2个不关联的表怎么办。。求大神啊 别沉啊- -老板要砍人的啊

[其他解释]

各位大大再帮帮忙想想办法啊。感激不尽啊
[其他解释]
谢谢ben,要怎么写呢?
 
DECLARE @qk  datetime,@jk datetime 
DECLARE @qj  datetime,@jj  datetime 

SET @qk='2011-06-21'SET @jk='2012-06-21'
SET @qj='2011-06-23'SET @jj='2012-06-22'
 
 DECLARE @WHERE1 NVARCHAR(MAX),@WHERE2 NVARCHAR(MAX),@WHERE3 NVARCHAR(MAX)  
  SELECT @WHERE1='CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND @jk'        ,
  @WHERE2='CONVERT(datetime,srq,112)BETWEEN @jj AND dateadd(dd,15,@jj)'        ,
  @WHERE3='CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,@jk) AND dateadd(dd,15,@jj)'         
   EXEC (N'SELECT (SELECT sum(nqhje) FROM t_qhb WHERE '+@WHERE1+')  


      /     
   (SELECT sum(nchje) FROM t_chb WHERE      '+@WHERE1+') AS 节前15天缺货率   
      ,   
     (SELECT sum(nqhje) FROM t_qhb WHERE      '+@WHERE2+')  
      /     (SELECT sum(nchje) FROM t_chb WHERE      '+@WHERE2+') AS 节后15天缺货率     ,   
    (SELECT sum(nqhje) FROM t_qhb WHERE      '+@WHERE3+')  
           /     (SELECT sum(nchje) FROM t_chb WHERE      '+@WHERE3+') AS 前后30天缺货率') 
消息 137,级别 15,状态 2,第 1 行
必须声明标量变量 "@jk"。
消息 137,级别 15,状态 2,第 3 行
必须声明标量变量 "@jk"。
消息 137,级别 15,状态 2,第 5 行
必须声明标量变量 "@jj"。
消息 137,级别 15,状态 2,第 6 行
必须声明标量变量 "@jj"。
消息 137,级别 15,状态 2,第 7 行
必须声明标量变量 "@jk"。
消息 137,级别 15,状态 2,第 8 行
必须声明标量变量 "@jk"。


[其他解释]
DECLARE @WHERE1 NVARCHAR(MAX),@WHERE2 NVARCHAR(MAX),@WHERE3 NVARCHAR(MAX)

SELECT @WHERE1='CONVERT(datetime,srq,112)BETWEEN?dateadd(dd,-15,@jk)?AND?@jk'
,@WHERE2='CONVERT(datetime,srq,112)BETWEEN?@jj?AND?dateadd(dd,15,@jj)'
,@WHERE3='CONVERT(datetime,srq,112)BETWEEN?dateadd(dd,-15,@jk)?AND?dateadd(dd,15,@jj)'

EXEC (N'SELECT?(SELECT?sum(nqhje)?FROM?t_qhb?WHERE?
'+@WHERE1+')
/
(SELECT?sum(nchje)?FROM?t_chb?WHERE?
'+@WHERE1+')?AS?节前15天缺货率
,
(SELECT?sum(nqhje)?FROM?t_qhb?WHERE?
'+@WHERE2+')
/
(SELECT?sum(nchje)?FROM?t_chb?WHERE?
'+@WHERE2+')?AS?节后15天缺货率
,
(SELECT?sum(nqhje)?FROM?t_qhb?WHERE?
'+@WHERE3+')
/
(SELECT?sum(nchje)?FROM?t_chb?WHERE?
'+@WHERE3+')?AS?前后30天缺货率'
)

[其他解释]

 DECLARE @WHERE1 NVARCHAR(MAX),@WHERE2 NVARCHAR(MAX),@WHERE3 NVARCHAR(MAX)  
  SELECT @WHERE1='CONVERT(datetime,srq,112)BETWEEN dateadd(dd,-15,'''+CONVERT(VARCHAR(10),@jk,112)+''') AND '''+CONVERT(VARCHAR(10),@jk,112)+''''        ,
  @WHERE2='CONVERT(datetime,srq,112) BETWEEN '''+CONVERT(VARCHAR(10),@jj,120)+''' AND dateadd(dd,15,'''+CONVERT(VARCHAR(10),@jj,120)+''')'        ,
  @WHERE3='CONVERT(datetime,srq,112) BETWEEN dateadd(dd,-15,'''+CONVERT(VARCHAR(10),@jk,120)+''') AND dateadd(dd,15,'''+CONVERT(VARCHAR(10),@jj,120)+''')

[其他解释]
关注SQL的信息。
[其他解释]
谢谢ben
  可以实现。不过如果要把这个结果当成一个表然后和别的select静态连接怎么实现比如
selelct * from 
(select * from table ) a,
 (select * from table1 ) b,
 (exec (N'SELECT (SELECT sum(nqhje) FROM t_qhb WHERE '+@WHERE1+')      


          /       
            (SELECT sum(nchje) FROM t_chb WHERE      '+@WHERE1+') AS 节前15天缺货率    
                  ,         (SELECT sum(nqhje) FROM t_qhb WHERE      '+@WHERE2+')      
                     /    
                      (SELECT sum(nchje) FROM t_chb WHERE      '+@WHERE2+') AS 节后15天缺货率    
                       ,        (SELECT sum(nqhje) FROM t_qhb WHERE      '+@WHERE3+')           
                          /     (SELECT sum(nchje) FROM t_chb WHERE      '+@WHERE3+') AS 前后30天缺货率') ) c


类似这样的意思怎么实现?
[其他解释]
,条件并不重复.应该没办法精简
[其他解释]
select * from ( 报表语句 ) t再链接
[其他解释]
如果是 2005 以上的版本 可以用 with 来优化,
否则就麻烦点,多写几个视图。
[其他解释]
列出你的表结构,和数据,说出你的需求和想法,大家帮你想办法
[其他解释]
分开算啊. 检索归检索, 计算归计算

热点排行