加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

SQLserver通过group和case按日期等分

(2020-02-07 10:20:26)
标签:

sql

case

group

when

cast

分类: 代码天地
SQL 数据库表通过 group 和 case 达到按日期等分的效果

1 数据库表 Table_A 的 结构  

id int  salary int  , val int  , dt datetime 
 

2 数据库表 Table_A 的 数据
select * from Table_A    

id salary  val dt
1 10        11  2020-01-01 
2 150        151  2020-01-01 
3 400        401  2020-01-02 
4 300        301  2020-01-05  
5 520        521  2020-02-01 
6 580        581  2020-02-01  
7 570        571  2020-02-02  
8 630        631  2020-02-03  
9 700        701   2020-02-04  
10 690        691   2020-02-05  
11 850        851  2020-02-06
12 1000       1001  2020-02-07
13 900        901  2020-02-08
14 950        951  2020-02-09 


3 按数值分类

SELECT   COUNT(*) as num , MAX(salary) as salary, MAX(val) as val FROM Table_A
GROUP BY
        CASE WHEN salary <= 500 THEN 1 
             WHEN salary > 500 AND salary <= 600  THEN 2
             WHEN salary > 600 AND salary <= 800  THEN 3 
             WHEN salary > 800 AND salary <= 1000 THEN 4 
        ELSE NULL END; 

结果如下:
num salary val
4 400 401
3 580 581
3 700 701
4 1000 1001

 4 按日期作为序号分类            

SELECT   COUNT(*) as num , MAX(salary) as salary, MAX(val) as val FROM Table_A
GROUP BY
        CASE WHEN dt <= CAST('2020/01/10' AS datetime)  THEN 1 
             WHEN dt > CAST('2020/01/31' AS datetime) AND dt <= CAST('2020/02/02' AS datetime)  THEN 2
             WHEN dt > CAST('2020/02/02' AS datetime) AND dt <= CAST('2020/02/05' AS datetime)  THEN 3 
             WHEN dt > CAST('2020/02/05' AS datetime) AND dt <= CAST('2020/02/09' AS datetime) THEN 4 
        ELSE NULL END;   


结果如下:
num salary val
4 400   401
3 580   581
3 700   701
4 1000 1001


5 按日期作为日期分类 

SELECT   COUNT(*) as num , MAX(salary) as salary, MAX(val) as val,MAX(dt) as dt FROM Table_A
GROUP BY
        CASE WHEN dt <= CAST('2020-01-10' AS datetime)  THEN CAST('2020-01-10' AS datetime) 
             WHEN dt > CAST('2020/01/31' AS datetime) AND dt <= CAST('2020/02/02' AS datetime)  THEN CAST('2020/01/31' AS datetime)
             WHEN dt > CAST('2020/02/02' AS datetime) AND dt <= CAST('2020/02/05' AS datetime)  THEN CAST('2020/02/02' AS datetime) 
             WHEN dt > CAST('2020/02/05' AS datetime) AND dt <= CAST('2020/02/09' AS datetime) THEN CAST('2020/02/05' AS datetime) 
        ELSE NULL END ;

结果如下:
num  salary val   dt
4 400   401   2020-01-05 
3 580   581   2020-02-02 
3 700   701   2020-02-05  
4 1000   1001  2020-02-09  


6 简化日期类型


SELECT   COUNT(*) as num , MAX(salary) as salary, MAX(val) as val,MAX(dt) as dt FROM Table_A
GROUP BY
        CASE WHEN dt <= '2020-01-10'   THEN'2020-01-10' 
             WHEN dt > '2020/01/31'  AND dt <='2020/02/02'   THEN '2020/01/31' 
             WHEN dt > '2020/02/02'  AND dt <= '2020/02/05'   THEN '2020/02/02'   
             WHEN dt > '2020/02/05'  AND dt <='2020/02/09'  THEN '2020/02/05' 
        ELSE NULL END ;


结果同上面的一样如下:
num  salary val   dt
4 400   401   2020-01-05 
3 580   581   2020-02-02 
3 700   701   2020-02-05  
4 1000   1001  2020-02-09  


理想日期类型

多数情况下,日期时间要达到时分秒的单位,因为sql 的 拼接子串varchar 和 nvarchar 最大长度是8000,为了能容纳更多的分类,可将结果分类从时间格式缩短为序号,返回数据集后再把序号转成时间即可

WHEN dt > '2020/01/31 03:09:23' AND dt <= '2020/02/02 06:18:46'   THEN 2

这样以来,按日期循环拼接语句,达到按日期等分的效果。
可以增加一个字段 xh int, 把上面的分类序号赋值给它,然后

 declare @st1 varchar(23), @st2 varchar(23)
 DECLARE @dt1 datetime , @dt2 datetime
 declare @secord_num bigint,@n int,@step int,@loop_num int
 select @st1='2013-06-15 15:58:56.000' , @st2='2013-06-22 16:11:52.000'
 select @dt1=CONVERT(datetime,@st1,120), @dt2=CONVERT(datetime,@st2,120)
 SELECT @secord_num=DATEDIFF(SECOND,@dt1,@dt2) --以秒为单位的时间段长度
 select @loop_num=100 -- 最终的分类个数
 select @step=@secord_num/@loop_num --一秒为单位的分类步长
 -- DATEADD(ss,xh*@step,@dt1)-- ss 单位秒, xh*@step,步长,@dt1 最小的日期时间
  update  [oo].[dbo].[Table_A] set dt=DATEADD(ss,xh*@step,@dt1) -- 按另一个字段xh,一次性修改日期时间dt

新的样例结果如下:

salary val   xh dt
10 11 1 2013-06-15 17:39:51 
150 151 2 2013-06-15 19:20:46 
400 401 3 2013-06-15 21:01:41 
300 301 4 2013-06-15 22:42:36 
520 521 5 2013-06-16 00:23:31 
580 581 6 2013-06-16 02:04:26 
570 571 7 2013-06-16 03:45:21 
630 631 8 2013-06-16 05:26:16 
700 701 9 2013-06-16 07:07:11 
690 691 10 2013-06-16 08:48:06 
850 851 11 2013-06-16 10:29:01 
1000 1001 12 2013-06-16 12:09:56 
900 901 13 2013-06-16 13:50:51 
950 951 14 2013-06-16 15:31:46 





0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有