存储过程自动生成显示 2016年1月1日 ~ 2025年12月31日 )

1、问题:  在Q群中一位小伙伴问题,然后当时就给出了一个简单的想法,今天就写了一个存储过程实现它,从最简单的字段一步步实现的
           

 

           Date_Key这列还需要这样转换一下,懒得转换了  Select CONVERT(varchar(100), GETDATE(), 111): 2006/05/16

2、首先,就是想用循环将  日期值(如: 2016-01-01 ~ 2025-12-31,季度值,  这2个字段显示出来),因为他们是主要的字段,其他转换一下即可

      写基本框框结构,然后再一段一段拼接上去

 

 

3、“表结构”(泛指,表、 存储过程)

         表结构(只看    t_YM_Week_Quarter        这一个就可):

/*
自动生成年月日、季度,表结构
*/
USE [testdb]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO
--Drop table t_YM_Week_Quarter 
GO
CREATE TABLE [dbo].[t_YM_Week_Quarter](           --------------作用于此表
    [cYMD] datetime NOT NULL,
    [cYear] [char](4) NOT NULL,
    [cMonth] [char](2) NOT NULL,
    [cYYYYMM] [char](6) NOT NULL,    
    [iWeekNo] [int] NOT NULL,
    [iQuarterNo] [int] NOT NULL,
    [cYMDmap] datetime NOT NULL,
) ON [PRIMARY]

GO

select * from t_YM_Week_Quarter


CREATE TABLE [dbo].[t_Y](
    [cYear] [char](4) NOT NULL,
) ON [PRIMARY]

GO
--drop table t_YMD
GO
CREATE TABLE [dbo].[t_YMD](
    [cYMD] datetime NOT NULL,
) ON [PRIMARY]

GO
------------------------
--drop table t_YMD_Quarter
GO
CREATE TABLE [dbo].[t_YMD_Quarter](
    [cYMD] datetime NOT NULL,
    [cQuarter] int NOT NULL,
) ON [PRIMARY]

GO
------------------------
--drop table t_YMD_Quarter
GO
CREATE TABLE [dbo].[t_YMD_Quarter](
    [cYMD] datetime NOT NULL,
    [cQuarter] int NOT NULL,
    
) ON [PRIMARY]

GO

--下面更新了之前试用了固定变量的部分

DROP PROC usp_YMD_Quarter
GO
CREATE PROC [dbo].[usp_YMD_Quarter] @sdate DATETIME,
                    @edate DATETIME
AS
BEGIN
      --SET @sdate = '2016-1-1'
      --SET @edate = '2025-12-31'

      --DECLARE @iYMD INT
      DECLARE @iDay INT
      set @iDay = 0
      --DECLARE @iYear INT
      DECLARE @cYMD datetime
      DECLARE @TotalDays int
      DECLARE @cQuarter int
      DECLARE @iWeekNo int
      
      DECLARE @cYear char(4)
      DECLARE @cMonth char(2)
      DECLARE @cYYYYMM char(6)
      
      DECLARE @cYMDmap char(8)
      
      set @TotalDays = DATEDIFF(day,@sdate,@edate)  --修改了此处,当时为了调试直接用了固定数据

      WHILE @iDay <= CAST(@TotalDays as int)         --iDay只是起循环作用,循环到'2016-1-1','2025-12-31'的差 = 3652就停止  
        BEGIN
            SET @cYMD=CONVERT(varchar(32),DATEADD(DD,@iDay,@sdate),112)       --select DATEADD(DD,1,'2016-1-1')
                                                                   
            SET @cYear = CAST(datepart(yyyy,@cYMD) as CHAR(4))    --select CAST(datepart(yyyy,'2016-01-01') as CHAR(4))
            --SET @cMonth = CAST(datepart(mm,@cYMD) as CHAR(2))
            SET @cMonth = CAST(Right(100+Month(datepart(mm,@cYMD)),2) as CHAR(2))    --这样可显示2位的月份,不足2位时前面补0
            
            SET @cYYYYMM = CAST(datepart(yyyy,@cYMD) as CHAR(4))+CAST(Right(100+Month(datepart(mm,@cYMD)),2) as CHAR(2))  --正确
                                          
            SET @iWeekNo = datepart(ww,@cYMD)
            SET @cQuarter = datepart(qq,@cYMD)       --select datepart(qq,'2016-7-1')
            
            SET @cYMDmap = CONVERT(varchar(32),@cYMD,112)        --select CONVERT(varchar(32),'2016-01-01',112)
            --SET @cYMDmap = @cYMD
            
            INSERT INTO dbo.t_YM_Week_Quarter                --,@cYMDmap  
                        (cYMD,cYear,cMonth,cYYYYMM,iWeekNo,iQuarterNo,cYMDmap)  --,@cYMDmap
            VALUES      (@cYMD,@cYear,@cMonth,@cYYYYMM,@iWeekNo,@cQuarter,@cYMDmap)

           SET @iDay=@iDay + 1
       END
END
                          
/*                     
--delete from t_YM_Week_Quarter                --convert(varchar(32),cYMD,23) as cYMD,cQuarter
               
exec usp_YMD_Quarter '2016-1-1', '2016-1-20'    
select convert(varchar(32),cYMD,23) as cYMD,iQuarterNo from t_YM_Week_Quarter order by cYMD                           
SELECT CONVERT(VARCHAR(32), cYMD, 23) as cYMD,
       cYear,
       cMonth,
       cYYYYMM,
       iWeekNo,
       iQuarterNo,
       CONVERT(VARCHAR(32), cYMDmap, 112) as cYMDmap
FROM   t_YM_Week_Quarter
ORDER  BY cYMD 

*/
GO

 




显示结果(截取了首位的部分):

 

 

......

 

 

 

 

 

---完成

 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面是思考部分,可以不用理会它(就是先在旁边写、拼接语句),最后再组合在一起

SELECT Datediff(dd, CONVERT(VARCHAR(7), Getdate(), 121) + '-01', CONVERT (VARCHAR(10), Dateadd(day, -1, Cast(CONVERT(VARCHAR(7), Dateadd(month, 1, Getdate()), 121)
                                                                                                             + '-01' AS DATETIME)), 121)) AS 天数
                                                                                                             
                                                                                                             
sp_helptext Getmonths               
CREATE FUNCTION Getmonths (@Month SMALLINT,  
                           @Year  INT)  
returns SMALLINT  
/*获取当月的天数*/  
AS  
  BEGIN  
      RETURN( Day(Dateadd(dd, -1, Dateadd(m, 1, Cast(@Year AS VARCHAR(4)) + '-'  
                                                + Cast(@Month AS VARCHAR(2)) + '-01'))) )  
  END 
  
select dbo.Getmonths('5','2020')        


SELECT Datepart(yyyy, OrderDate) AS OrderYear,
       Datepart(mm, OrderDate)   AS OrderMonth,
       Datepart(dd, OrderDate)   AS OrderDay
FROM   Orders
WHERE  OrderId = 1 
                                 
                                 
                                 
Select REPLACE(CONVERT(varchar(100), GETDATE(), 112)+CONVERT(varchar(100), GETDATE(), 8),':','')  

select * from orders      
select CONVERT(varchar(32),OrderDate,112) from Orders       

-----------------------------------------------------
       
Select   Right(100+Month(GetDate()),2)     
select Right(100+Month(datepart(MM,'2016-01-01')),2)
select CAST(Right(100+Month(datepart(MM,'2016-01-01')),2) as CHAR(2)) as MM

Select CAST(datepart(yyyy,'2016-01-01') as CHAR(4)) as YYYY,
       CAST(Right(100+Month(datepart(MM,'2016-01-01')),2) as CHAR(2)) as MM,
       CAST(datepart(yyyy,'2016-01-01') as CHAR(4)) + CAST(Right(100+Month(datepart(MM,'2016-01-01')),2) as CHAR(2)) as YYYYMM




-----------------------------------------------------------------------------
 declare @TotalDays
 set @TotalDays = select DATEDIFF(day,'2016-1-1','2025-12-31')
select @TotalDays as TotalD                                                             
                                              
--drop proc usp_Y
GO
--drop PROC usp_Y
CREATE PROC usp_Y
    @cYear CHAR(4)
as
begin
     DECLARE @iYear int
         DECLARE @iDay int
     SET @iYear=2016
 
      WHILE @iYear<2026
      BEGIN
                 SET @cYear=Cast(@iYear AS CHAR(4))
                     INSERT INTO dbo.t_Y
                                               (
                                     cYear )
                        VALUES (@cYear)
        
                    
                     SET @iYear=@iYear + 1
      END
END
                          
/*                                    
exec usp_Y 2016     
select * from t_Y                             
*/

-------------------------------------------------------------------------------------------------------------------------------
任务虽然完成,但还是感觉好 Low,看看是否还有其他更简便的方法生成,想结果应该还是有的,......
-------------------------------------------------------------------------------------------------------------------------------
逐渐注意到这类应用(CTE --- Common Table Expressions,从2005就开始了,2000不知道是否有):
Expert T-SQL Window Functions in SQL Server 2019,Chapter 4: Calculating Running and Moving Aggregates
The query was very easy to write and runs pretty fast. It ran in less than 100
milliseconds on my Azure virtual machine against 100,000 rows

 

posted @ 2020-05-20 22:18  CDPJ  阅读(239)  评论(0编辑  收藏  举报