sql 中存储过程while循环select 计算百分比效率低 请教哪里问题

weixin_42669646 2018-07-11 05:08:55
传入两个日期,计算两个日期间每小时条数除6的百分比
查一天就要27秒


ALTER PROCEDURE [dbo].[gethour]
@a datetime,
@b datetime,
@c nchar(50)
AS
BEGIN
declare @xiaoshi int,@chushu float,@num int

set @chushu = 6
set @xiaoshi = DATEDIFF(Hour, @a, @b)
set @num=0


while @num<@xiaoshi
begin
select (select top 1 (cast( convert (decimal(18,2),100*cast((select count(*) from [g_zdcjl].[dbo].[zdcjl_data] where datediff(HH,Dtime,@a)=0 and 系统=@c) as float)/@chushu )as varchar)+'%')from [g_zdcjl].[dbo].[zdcjl_data] )as 百分比,@a as 时间,@c as 点位
set @a=dateadd(HOUR,1,@a)
set @num=@num+1
end

END
...全文
209 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjcxc 2018-07-12
  • 打赏
  • 举报
回复
能直接查询搞定的,就不要循环,所以参考楼上
丰云 2018-07-12
  • 打赏
  • 举报
回复
用我的方法,运算最节省,效率超高

-- params:startTime = '2017-01-01', endTime = '2018-08-01'
select COUNT(1) * 100 / 6
, DATEADD(HOUR, hs, @startTime) as tm
from (
select hs = DATEDIFF(HOUR, startTime, CreateTime)
from tbName
where CreateTime > startTime
and CreateTime < @endTime) as t
group by hs
weixin_42669646 2018-07-12
  • 打赏
  • 举报
回复
引用 6 楼 weixin_42669646 的回复:
[quote=引用 5 楼 shinger126 的回复:]
这个需求,为啥不用自然时间的小时来计算?还非要用传入的开始时间,你传入是开始时间,只是一个日期吧,并不带时间的。
这样的话:这样岂不是更有效率?数据量大的话,还可以在表zdcjl_data上新增一个计算列,值为CONVERT(VARCHAR(13) ,Dtime,120) ,然后直接用这个列去汇总每小时的条数来计算
;WITH t AS (
SELECT CONVERT(VARCHAR(13) ,Dtime,120) dt,COUNT(*) cts FROM [g_zdcjl].[dbo].[zdcjl_data]
where dtime between @starttime and @endtime
GROUP BY CONVERT(VARCHAR(13) ,Dtime,120))
SELECT CAST(CAST(cts/6.00 AS DECIMAL(18,2)) AS VARCHAR(20))+'%',dt FROM t


谢谢各位,这个速度确实快。。但是为什么cts取出的值是0.24呢?应该每小时间有6条数据 实在搞不懂 望指教[/quote]
犯蠢啦。谢谢大神
weixin_42669646 2018-07-12
  • 打赏
  • 举报
回复
引用 5 楼 shinger126 的回复:
这个需求,为啥不用自然时间的小时来计算?还非要用传入的开始时间,你传入是开始时间,只是一个日期吧,并不带时间的。
这样的话:这样岂不是更有效率?数据量大的话,还可以在表zdcjl_data上新增一个计算列,值为CONVERT(VARCHAR(13) ,Dtime,120) ,然后直接用这个列去汇总每小时的条数来计算
;WITH t AS (
SELECT CONVERT(VARCHAR(13) ,Dtime,120) dt,COUNT(*) cts FROM [g_zdcjl].[dbo].[zdcjl_data]
where dtime between @starttime and @endtime
GROUP BY CONVERT(VARCHAR(13) ,Dtime,120))
SELECT CAST(CAST(cts/6.00 AS DECIMAL(18,2)) AS VARCHAR(20))+'%',dt FROM t


谢谢各位,这个速度确实快。。但是为什么cts取出的值是0.24呢?应该每小时间有6条数据 实在搞不懂 望指教
shinger126 2018-07-12
  • 打赏
  • 举报
回复
这个需求,为啥不用自然时间的小时来计算?还非要用传入的开始时间,你传入是开始时间,只是一个日期吧,并不带时间的。
这样的话:这样岂不是更有效率?数据量大的话,还可以在表zdcjl_data上新增一个计算列,值为CONVERT(VARCHAR(13) ,Dtime,120) ,然后直接用这个列去汇总每小时的条数来计算
;WITH t AS (
SELECT CONVERT(VARCHAR(13) ,Dtime,120) dt,COUNT(*) cts FROM [g_zdcjl].[dbo].[zdcjl_data]
where dtime between @starttime and @endtime
GROUP BY CONVERT(VARCHAR(13) ,Dtime,120))
SELECT CAST(CAST(cts/6.00 AS DECIMAL(18,2)) AS VARCHAR(20))+'%',dt FROM t
二月十六 2018-07-11
  • 打赏
  • 举报
回复
那个select top 1没啥用吧
ALTER PROCEDURE [dbo].[gethour]
@a DATETIME,
@b DATETIME,
@c NCHAR(50)
AS
BEGIN
DECLARE @xiaoshi INT,
@chushu FLOAT,
@num INT;

SET @chushu = 6;
SET @xiaoshi = DATEDIFF(HOUR, @a, @b);
SET @num = 0;


WHILE @num < @xiaoshi
BEGIN
SELECT (CAST(CONVERT( DECIMAL(18, 2),
100 * CAST(
(
SELECT COUNT(*)
FROM [g_zdcjl].[dbo].[zdcjl_data]
WHERE DATEDIFF(HH, Dtime, @a) = 0
AND 系统 = @c
) AS FLOAT) / @chushu
) AS VARCHAR) + '%'
) AS 百分比,
@a AS 时间,
@c AS 点位;
SET @a = DATEADD(HOUR, 1, @a);
SET @num = @num + 1;
END;

END;

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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