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次了。。
[其他解释]
你这两个表没得关系 汇总时间也不一样 那基本上没法怎么精简了 你的写法也对 我刚刚看成了时间范围是一样的 那样的话就可以精简一下 不好意思
[其他解释]
不是啊。我汇总时间是一样啊
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个语句,分别从数据库里求出统计值,然后在你的程序里去求除法.
兄弟,要学会变通.
[其他解释]
不是的。。
我是把这些结果放进一个select里面。分成3句单独看是短了。但是都得放进程序里面去的。
程序sql字符就超出了。所以希望把每天重复写的条件语句能不能整合起来?或者用一个什么变量代替也行?
[其他解释]
呵呵 。谢谢我以后会注意。
不过现在我是用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 来优化,
否则就麻烦点,多写几个视图。
[其他解释]
列出你的表结构,和数据,说出你的需求和想法,大家帮你想办法
[其他解释]
分开算啊. 检索归检索, 计算归计算