improve or shorten sql query select Result on table [Date] - sql

I have a table of Date and a column of ID,FromDate and ToDate shown at below
ID FromDate ToDate
-- -------------- --------------
1 2013-06-10 00:00:00 2013-06-30 00:00:00
2 2013-05-10 00:00:00 2013-06-10 00:00:00
3 2012-08-01 00:00:00 2012-12-31 00:00:00
4 2013-07-10 00:00:00 2013-07-30 00:00:00
I doing a checking query and make a column as Result whether is active, inactive or expired by using [getdate] shown at below
Select ID, FromDate, ToDate,
(case when convert(varchar(8),FromDate,112) <= convert(varchar(8),getdate(),112)
and convert(varchar(8),ToDate,112) <= convert(varchar(8),getdate(),112) then 'Expired'
when convert(varchar(8),FromDate,112) <= convert(varchar(8),getdate(),112)
and convert(varchar(8),ToDate,112) >= convert(varchar(8),getdate(),112) then 'Active'
when convert(varchar(8),FromDate,112) >= convert(varchar(8),getdate(),112)
and convert(varchar(8),ToDate,112) >= convert(varchar(8),getdate(),112) then 'Inactive' end )'Result'
from Date
It will show the correct result
ID FromDate ToDate Result
-- -------------- -------------- --------
1 2013-06-10 00:00:00 2013-06-30 00:00:00 Active
2 2013-05-10 00:00:00 2013-06-10 00:00:00 Expired
3 2012-08-01 00:00:00 2012-12-31 00:00:00 Expired
4 2013-07-10 00:00:00 2013-07-30 00:00:00 Inactive
But my Case query is too long, is there anyway to shorten the code or improve the performance?

How about the query:
Select
ID,
FromDate,
ToDate,
(case when convert(varchar(8),ToDate,112) <= convert(varchar(8),getdate(),112) then 'Expired'
when convert(varchar(8),getdate(),112) between convert(varchar(8),FromDate,112) and convert(varchar(8),ToDate,112) then 'Active'
when convert(varchar(8),FromDate,112) >= convert(varchar(8),getdate(),112) then 'Inactive' end )'Result'
from Date
Given ToDate is greater than FromDate.

SELECT ID, FromDate, ToDate,
CASE WHEN ToDateStr <= NowStr THEN 'Expired'
WHEN NowStr BETWEEN FromDateStr AND ToDateStr THEN 'Active'
ELSE 'Inactive' END AS Result
FROM (
SELECT
ID, FromDate, ToDate,
CONVERT(varchar(8),FromDate,112) AS FromDateStr,
CONVERT(varchar(8),ToDate,112) AS ToDateStr,
CONVERT(varchar(8),getdate(),112) AS NowStr
FROM Date) A
Given that the From date is always lower or equal than the To Date

select id, fromDate, toDate,
case
when daysFromStart > 0 AND daysToEnd > 0 then 'Active'
when daysFromStart > 0 AND daysToEnd < 0 then 'Expired'
when daysFromStart < 0 AND daysToEnd > 0 then 'Inactive'
end
from
(
select
id, fromDate, toDate,
DATEDIFF(day, fromDate, getdate()) as daysFromStart,
DATEDIFF(day, getdate(), toDate) as daysToEnd
from orders
) t
SQL fiddle

Related

Time until midnight between two date and time columns

I need help with my query to calculate the time until midnight between two date and time columns
break down by day
This is the main table:
ID
Start_Time
End_time
DateDiff
32221
01-01-2022 13:10:00
01-03-2022 13:10:00
2880
My query:
SELECT
start_time.ID,
start_time.Date_Time AS Start_time,
end_time.Date_Time AS End_time,
DATEDIFF(minute, start_time.Date_Time, end_time.Date_Time) AS DateDiff
FROM
Main
what I need is similar to this:
ID
Date_start
End_time
DateDiff
32221
01-01-2022 13:10:00
01-01-2022 23:59:59
654
32221
01-02-2022 00:00:00
01-02-2022 23:59:59
1440
32221
01-03-2022 00:00:00
01-03-2022 13:10:00
781
how i can do that?
You can loop through the times, always adding the time untill midnight, untill your 'start_time + 1 day' is bigger than your end_time.
The below code can be run directly in SQL (mind the date notation, my SQL is in united states notation, so if yours is in Europe this will give you back results for 3 months instead of 3 days);
DECLARE #start_time datetime2 = '01/01/2022 13:00:00';
DECLARE #end_time datetime2 = '03/01/2022 14:00:00';
DECLARE #daily_end_time datetime2=NULL;
DECLARE #Table Table (start_time datetime2, end_time datetime2, diff nvarchar(8));
DECLARE #diff_minutes_start int = DATEDIFF(MINUTE,#start_time,DateDiff(day,0,dateadd(day,1,#start_time)));
DECLARE #diff_minutes_end int = DATEDIFF(minute,#end_time,DateDiff(day,0,dateadd(day,1,#end_time)))
SET #daily_end_time = DATEADD(mi,#diff_minutes_start,#start_time)
WHILE #daily_end_time < #end_time
BEGIN
INSERT INTO #Table (start_time,end_time,diff)
VALUES (
#start_time,
CASE WHEN DATEADD(day,1,#daily_end_time) > #end_time THEN #end_time ELSE
#daily_end_time END,
CASE WHEN DATEADD(day,1,#daily_end_time) > #end_time THEN #diff_minutes_end ELSE
#diff_minutes_start END )
SET #daily_end_time = DATEADD(mi,#diff_minutes_start,#start_time)
SET #start_time = DATEADD(mi,1,#daily_end_time);
select #diff_minutes_start =
DATEDIFF(MINUTE,#start_time,DateDiff(day,0,dateadd(day,1,#start_time)));
select #diff_minutes_end = DATEDIFF(minute,#end_time,DateDiff(day,0,dateadd(day,1,#end_time)))
END
SELECT * FROM #Table
And the results:
You may use a recursive CTE as the following:
With CTE As
(
Select ID, Start_Time, End_time, DATEADD(Second, -1, DATEADD(Day, DATEDIFF(Day,0, Start_Time), 1)) et
From main
Union All
Select C.ID, DATEADD(Second, 1, C.et), C.End_time, DATEADD(Day, 1, C.et)
From CTE C Join main T
On C.ID = T.ID
Where DATEADD(Second, 1, C.et) <= C.End_time
)
Select ID, Start_Time,
Case When End_Time <= et Then End_Time Else et End As End_Time,
DATEDIFF(Minute, Start_Time, DATEADD(Second, 1, Case When End_Time <= et Then End_Time Else et End)) As [DateDiff]
From CTE
Order By ID, Start_Time
See a demo with extended data sample from db<>fiddle.
You can also solve this with a tally table, using the expanded (to show different cases) sample data
ID
StartTime
EndTime
32221
2022-01-01 13:10:00
2022-01-03 13:10:00
32222
2022-02-02 10:10:00
2022-02-02 17:10:00
32223
2022-03-03 19:10:00
2022-03-04 08:10:00
32224
2022-04-04 19:10:00
2022-04-08 08:10:00
and the code
with cteSampleData as ( --Enter some sample data, include spans of 0, 1, and >1 days
SELECT * --Note that we need CONVERT to make sure the dates are treated as datetime not string!
FROM (VALUES(32221, CONVERT(datetime2(0), '01-01-2022 13:10:00'), CONVERT(datetime2(0), '01-03-2022 13:10:00') )
, (32222, '02-02-2022 10:10:00', '02-02-2022 17:10:00')
, (32223, '03-03-2022 19:10:00', '03-04-2022 08:10:00')
, (32224, '04-04-2022 19:10:00', '04-08-2022 08:10:00')
) as Samp(ID, StartTime, EndTime)
), cteWithControl as ( --Add some fields to make testing cledarer - you could do this as part of a subsequent step instead
SELECT *
, CONVERT(date, StartTime) as StartDate , CONVERT(date, EndTime) as EndDate
, DATEDIFF(day, StartTime , EndTime) as DiffDays
--, DATEDIFF(day, CONVERT(date, StartTime) , CONVERT(date, EndTime)) as DiffDays
FROM cteSampleData
), cteTally as ( --Get a list of integers to represent days, assume nothing lasts longer than a year
SELECT top 365 ROW_NUMBER() over (ORDER BY name) as Tally
FROM sys.objects --just a table we know has over 300 rows, look up tally tables for other generation methods
)--The real work begins below, partition the data into "same day" and "multi-day" spans
, cteSet as (
SELECT ID, StartTime, EndTime, DiffDays, 1 as DayNumber
FROM cteWithControl WHERE DiffDays = 0
UNION ALL
SELECT ID --For multi-day, cross with the tally table and treat first and last days special
, CASE WHEN T.Tally = 1 THEN StartTime --For the first day the start time is the real time
ELSE DATEADD (day, T.Tally - 1, startdate) END as StartTime --Otherwise it's the start of the day
, CASE WHEN T.Tally = DiffDays + 1 THEN EndTime --For the last day the end is the real end
ELSE DATEADD (second, -1, CONVERT(DATETIME2(0), DATEADD (day, T.Tally, startdate)))
END as EndTime --otherwise 1 second less than the next day
, DiffDays, Tally as DayNumber
FROM cteWithControl as D CROSS JOIN cteTally as T
WHERE DiffDays > 0 AND T.Tally <= D.DiffDays + 1
)--Now we display the results and calculate the length (in minutes) of each span
SELECT *
, DATEDIFF(MINUTE, StartTime, EndTime) as DateDiff
FROM cteSet
ORDER BY ID, DayNumber
we get the output
ID
StartTime
EndTime
DiffDays
DayNumber
DateDiff
32221
2022-01-01 13:10:00
2022-01-01 23:59:59
2
1
649
32221
2022-01-02 00:00:00
2022-01-02 23:59:59
2
2
1439
32221
2022-01-03 00:00:00
2022-01-03 13:10:00
2
3
790
32222
2022-02-02 10:10:00
2022-02-02 17:10:00
0
1
420
32223
2022-03-03 19:10:00
2022-03-03 23:59:59
1
1
289
32223
2022-03-04 00:00:00
2022-03-04 08:10:00
1
2
490
32224
2022-04-04 19:10:00
2022-04-04 23:59:59
4
1
289
32224
2022-04-05 00:00:00
2022-04-05 23:59:59
4
2
1439
32224
2022-04-06 00:00:00
2022-04-06 23:59:59
4
3
1439
32224
2022-04-07 00:00:00
2022-04-07 23:59:59
4
4
1439
32224
2022-04-08 00:00:00
2022-04-08 08:10:00
4
5
490

SQL: Get results of time series of days backwards

Given is a table of stock values for entities saved every day. I would like to get:
Give all entities which are out of stock (Qty = 0) today and were not out of stock the day before.
And this for the day before yesterday compared to the day before the day beford yesterday. And so on.
My approach works, but I have to create the part in the WHERE condition manually.
How about a query for the whole year 2019?
#standardSQL
WITH
TableStockDaily AS (
SELECT TIMESTAMP('2019-10-10 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-10 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-10 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-11 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-11 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-11 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-12 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-12 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-12 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-13 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-13 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-13 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-14 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-14 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-14 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-15 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-15 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-15 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-16 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-16 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-16 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty
)
SELECT
sd1.ExportDate AS DateOutOfStock,
sd2.ExportDate AS DateNotOutOfStock,
sd1.EntityId AS EntityId,
sd1.Qty AS Qty1,
sd2.Qty AS Qty2
FROM
TableStockDaily sd1
LEFT JOIN
TableStockDaily sd2
ON
sd1.EntityId = sd2.EntityId
WHERE
sd1.Qty = 0
AND sd2.Qty > 0
AND sd1.ExportDate > sd2.ExportDate
AND
(
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -1 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -2 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -2 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -2 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -6 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -6 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -6 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -7 DAY)
)
)
I think that you are looking for LAG(). This window function can be used to recover the value of a given column within a group of recrods (here, records sharing the same EntityID) and according to a sorting criteria (here ExportDate):
SELECT *
FROM (
SELECT
EntityId,
ExportDate AS DateOutOfStock,
Qty AS QtyOutOfStock,
LAG(ExportDate) OVER(PARTITION BY EntityId ORDER BY ExportDate) AS DateNotOutOfStock,
LAG(Qty) OVER(PARTITION BY EntityId ORDER BY ExportDate) AS QtyNotOutOfStock
FROM
TableStockDaily sd1
) x
WHERE QtyOutOfStock = 0 AND QtyNotOutOfStock > 0

Split datetime range on a specific date into 2 records

Let's give a datetime 2019-04-22 00:00:00.000 (midnight of 22 April 2019)
Now I have a table of records that contains a StartDate and EndDate
ID StartDate EndDate
--------------------------------------------------------------------------
1 2019-04-15 00:00:00.000 2019-04-18 00:00:00.000
2 2019-04-16 00:00:00.000 2019-04-28 00:00:00.000
3 2019-04-23 00:00:00.000 2019-04-25 00:00:00.000
How can I split record with ID = 2 so that I get two records:
record one start date: 2019-04-16 00:00:00.000 and end date: 2019-04-21 23:59:59.000
record two start date: 2019-04-22 00:00:00.000 and end date: 2019-04-28 00:00:00.000
Basically if a range has the start date before 2019-04-22 00:00:00.000 and end date after 2019-04-22 00:00:00.000 then split that record into two records where the end date will be midnight before 2019-04-22 00:00:00.000 for the first record and start date will become 2019-04-22 00:00:00.000 for the second record.
I'd do a UNION ALL, where the first SELECT returns all rows starting before given datetime, and the second SELECT returns all rows ending after that datetime. Something like:
select id, startdate, case when EndDate < '2019-04-22 00:00:00.000' then EndDate
else '2019-04-22 00:00:00.000' end EndDate
from tablename
where startdate < '2019-04-22 00:00:00.000'
UNION ALL
select id, case when startdate > '2019-04-22 00:00:00.000' then startdate
else '2019-04-22 00:00:00.000' end,
EndDate
from tablename
where EndDate > '2019-04-22 00:00:00.000'
The case expressions are there to adjust start or end time for the overlapping rows, those who are splitted into two separate rows.
You can use the following solution:
DECLARE #splitDate DATE = '2019-04-22 00:00:00.000';
SELECT ID, StartDate, (select min(i) from (values (test.EndDate), (#splitDate)) AS T(i)) AS EndDate
FROM table_name WHERE StartDate < #splitDate
UNION ALL
SELECT ID, (select max(i) from (values (test.StartDate), (#splitDate)) AS T(i)) AS StartDate, EndDate
FROM table_name WHERE EndDate > #splitDate
demo on dbfiddle.uk

Get every 2 weeks on particular days SQL Server

I have a query getting the days in particular day that I selected and show the days in a month. My problem is that I need every two weeks of the month. And I also need to get long date format: dddd, dd MMMM yyyy and eliminate the time. Please help me.
DECLARE #startDate DATETIME = '9/1/2019'
DECLARE #endDate DATETIME = '12/31/2019'
DECLARE #dayOfWeek INT = 1;
WITH cte_Recursion AS
(
SELECT #startDate AS [Date]
UNION ALL
SELECT DATEADD(DAY, 1, [Date])
FROM cte_Recursion
WHERE [Date] < #endDate
)
SELECT [Date]
FROM cte_Recursion
WHERE DATEPART(WEEKDAY, [Date]) = #dayOfWeek
OPTION (MAXRECURSION 0)
The data returned looks like this:
2019-09-01 00:00:00.000
2019-09-08 00:00:00.000
2019-09-15 00:00:00.000
2019-09-22 00:00:00.000
2019-09-29 00:00:00.000
2019-10-06 00:00:00.000
2019-10-13 00:00:00.000
2019-10-20 00:00:00.000
2019-10-27 00:00:00.000
2019-11-03 00:00:00.000
2019-11-10 00:00:00.000
2019-11-17 00:00:00.000
2019-11-24 00:00:00.000
And I need to get like this (every other week):
2019-09-01 00:00:00.000
2019-09-15 00:00:00.000
2019-09-29 00:00:00.000
2019-10-13 00:00:00.000
2019-10-27 00:00:00.000
2019-11-10 00:00:00.000
2019-11-24 00:00:00.000
By changing your CTE to start on the correct day of the week, you can then change the recursion to add 14 days instead of 1, giving you the desired result without further manipulation:
DECLARE #startDate DATETIME = '9/1/2019'
DECLARE #endDate DATETIME = '12/31/2019'
DECLARE #dayOfWeek INT = 1;
WITH cte_Recursion AS
(SELECT DATEADD(DAY, ((#dayOfWeek - DATEPART(WEEKDAY, #startDate)) % 7 + 7) %7, #startDate) AS [Date]
UNION ALL SELECT DATEADD(DAY, 14, [Date])
FROM cte_Recursion
WHERE DATEADD(DAY, 14, [Date]) < #endDate)
SELECT [Date] FROM cte_Recursion
Output:
Date
01/09/2019 00:00:00
15/09/2019 00:00:00
29/09/2019 00:00:00
13/10/2019 00:00:00
27/10/2019 00:00:00
10/11/2019 00:00:00
24/11/2019 00:00:00
08/12/2019 00:00:00
22/12/2019 00:00:00
Demo on dbfiddle
To change the date format to dddd, dd MMMM yyyy, simply replace the final SELECT with:
SELECT FORMAT([Date], 'dddd, dd MMMM yyyy') AS [Date] FROM cte_Recursion
Output:
Date
Sunday, 01 September 2019
Sunday, 15 September 2019
Sunday, 29 September 2019
Sunday, 13 October 2019
Sunday, 27 October 2019
Sunday, 10 November 2019
Sunday, 24 November 2019
Sunday, 08 December 2019
Sunday, 22 December 2019
Demo on dbfiddle
you can use it :
DECLARE #startDate DATETIME = '9/1/2019'
DECLARE #endDate DATETIME = '12/31/2019'
DECLARE #dayOfWeek INT = 1;
WITH cte_Recursion AS
(
SELECT #startDate AS [Date]
UNION ALL SELECT DATEADD(DAY, 1, [Date])
FROM cte_Recursion WHERE [Date] < #endDate
)
SELECT [Date] FROM cte_Recursion
WHERE DATEPART(WEEKDAY, [Date]) = #dayOfWeek
and DATEPART(WEEK, [Date]) % 2 = 0
OPTION (MAXRECURSION 0)
You could use a recursive CTE as
WITH CTE AS
(
SELECT '2019-09-01 00:00:00.000' ADate
UNION SELECT '2019-09-08 00:00:00.000'
UNION SELECT '2019-09-15 00:00:00.000'
UNION SELECT '2019-09-22 00:00:00.000'
UNION SELECT '2019-09-29 00:00:00.000'
UNION SELECT '2019-10-06 00:00:00.000'
UNION SELECT '2019-10-13 00:00:00.000'
UNION SELECT '2019-10-20 00:00:00.000'
UNION SELECT '2019-10-27 00:00:00.000'
UNION SELECT '2019-11-03 00:00:00.000'
UNION SELECT '2019-11-10 00:00:00.000'
UNION SELECT '2019-11-17 00:00:00.000'
UNION SELECT '2019-11-24 00:00:00.000'
),
F AS
(
SELECT CAST('2019-09-01 00:00:00.000' AS DATETIME) ADate
UNION ALL
SELECT DATEADD(Day, 14, F.ADate)
FROM F
WHERE ADate < '2019-11-24 00:00:00.000'
)
SELECT *
FROM F;

how to display weekdays from below two days (Monday and Friday)?

how to display weekdays from below two days (Monday and Friday) Using SQL QUERY?
Date_From= 01/03/2011
Date_To =15/03/2011
I need output like below
Date_From Date_To
01/03/2011 01/03/2011
04/03/2011 04/03/2011 'Friday
05/03/2011 06/03/2011
07/03/2011 07/03/2011 'Monday
08/03/2011 10/03/2011
11/03/2011 11/03/2011 'Friday
12/03/2011 13/03/2011
14/03/2011 14/03/2011 'Monday
15/03/2011 15/03/2011
hoping your help
select
t1.Date_From,
t1.Date_To,
case when DATENAME(dw,t1.Date_to) IN ('friday','monday') THEN DATENAME(dw,t1.Date_to) else NULL END
from table t1
This is using Oracle. I can get the 15th to show up if I use Oracle analytic functions, but I don't know of a portable way to get the result in one row to depend on the existence of other rows. Also, due to the Cartesian product, do not use this without limiting it to a small number of rows.
select to_char(d1.d, 'DD/MM/YYYY')
, to_char(d2.d, 'DD/MM/YYYY')
, decode(d1.n, 'MONDAY', '''Monday', 'FRIDAY', '''Friday')
from (select to_date('2011-02-28') + rownum as d
, to_char(to_date('2011-02-28') + rownum, 'FMDAY') as n
from user_objects where rownum <= 15) d1
, (select to_date('2011-02-28') + rownum as d
, to_char(to_date('2011-02-28') + rownum, 'FMDAY') as n
from user_objects where rownum <= 15) d2
where d1.d <= d2.d
and d2.d - d1.d < 7
and ((d1.d = d2.d and d1.n in ('MONDAY', 'FRIDAY'))
or (d1.n = 'TUESDAY' and d2.n = 'THURSDAY')
or (d1.n = 'SATURDAY' and d2.n = 'SUNDAY'))
order by d1.d, d2.d;
This is for SQL Server 2005+.
DECLARE #Date_From datetime, #Date_To datetime;
SET #Date_From = '20110301';
SET #Date_To = '20110315';
WITH datelist AS (
SELECT
Date = #Date_From,
GroupID = 1
UNION ALL
SELECT
Date = DATEADD(day, 1, Date),
GroupID = CASE
WHEN DATENAME(dw, Date) IN ('Sunday', 'Monday', 'Thursday', 'Friday')
THEN 1
ELSE 0
END + GroupID
FROM datelist
WHERE Date < #Date_To
)
SELECT
Date_From = MIN(Date),
Date_To = MAX(Date)
FROM datelist
GROUP BY GroupID
Output:
Date_From Date_To
----------------------- -----------------------
2011-03-01 00:00:00.000 2011-03-03 00:00:00.000
2011-03-04 00:00:00.000 2011-03-04 00:00:00.000
2011-03-05 00:00:00.000 2011-03-06 00:00:00.000
2011-03-07 00:00:00.000 2011-03-07 00:00:00.000
2011-03-08 00:00:00.000 2011-03-10 00:00:00.000
2011-03-11 00:00:00.000 2011-03-11 00:00:00.000
2011-03-12 00:00:00.000 2011-03-13 00:00:00.000
2011-03-14 00:00:00.000 2011-03-14 00:00:00.000
2011-03-15 00:00:00.000 2011-03-15 00:00:00.000