简体   繁体   中英

Get data from the last day of the month without the use of loops or variables

I wrote a query that should select the last record of each month in a year. I'd like to create a View based on this select, that I could run later in my project, but unfortunately I can't use any while loops or variables in a view command. Is there a way to select all these records - last days of a month in a View that I can use later?

My desired effect of the view:

在此处输入图片说明

The query that I'm trying to implement in a view:

DECLARE @var_day01 DATETIME;
DECLARE @month int;
SET @month = 1;
DROP TABLE IF EXISTS #TempTable2;
CREATE TABLE #TempTable2 (ID int, date datetime, INP2D float, INP3D float, ID_device varchar(max));
WHILE @month < 13
BEGIN
SELECT @var_day01 = CONVERT(nvarchar, date)  FROM (SELECT TOP 1 * FROM data
WHERE DATEPART(MINUTE, CONVERT(nvarchar, date)) = '59'
AND
MONTH(CONVERT(nvarchar, date)) = (CONVERT(nvarchar, @month))
ORDER BY date DESC
 ) results
ORDER BY date DESC;

INSERT INTO #TempTable2 (ID, date, INP2D,INP3D,ID_device) 
SELECT * FROM data
WHERE DATEPART(MINUTE, CONVERT(nvarchar, date)) = '59'
AND
MONTH(CONVERT(nvarchar, date)) = (CONVERT(nvarchar, @month))
AND
DAY(CONVERT(nvarchar, date)) = CONVERT(datetime, DATEPART(DAY, @var_day01))
ORDER BY date DESC
PRINT @var_day01
SET @month = @month +1;
END


SELECT * FROM #TempTable2;

If you are actually just after the single most recent row for each month, there is no need for a while loop to achieve this. You just need to identify the max date value for each month and then filter your source data for those for those rows.

One way to achieve this is via a row_number window function:

declare @t table(id int,dt datetime2);
insert into @t values(1,getdate()-40),(2,getdate()-35),(3,getdate()-25),(4,getdate()-10),(5,getdate());

select id
      ,id_device
      ,dt
from(select id
           ,id_device
           ,dt
           ,row_number() over (partition by id_device, year(dt), month(dt) order by dt desc) as rn
     from @t
    ) as d
where rn = 1;

You can add a simple where to your select statement, in where clause you will add one day to the date field and then select the day from the resultant date . If the result date is 1 then only you will select that record

the where clause for your query will be : Where Day(DATEADD(d,1,[date])) = 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM