Philippe Renaud
asked on
Help with SQL Query
Hello EE,
I need to do a SQL Query.
I have a table called Closing_Date
in this table, the columns are: Date, Description
For example, values can be :
07/01/2020 Canada Day
07/10/2020 Summer vacation
07/11/2020 Summer Vacation
07/12/2020 Summer Vacation
......
12/25/2020 Christmas
etc..
in another table, let's call it TABLE_A i have 4 columns :
JobNo, JobDate, NbDays, DeliveryDate
values for example can be :
001, 04/11/2019, 68, 02/01/2020
002 04/15/2020, 56, 08/01/2020
003, 05/05/2020, 68, 08/01/2020
My question is, and maybe you already see me coming with this question :
I need to get a "ResultDate" that will grab for a JobNo, the JobDate and add the NbDays to it and see if I go beyond the DelieveryDate. but WITHOUT counting the days in the Table Closing_Date.
so if we add 68 days to the JobDate, and it goes beyond 08/01/2020, well maybe its not true if we remove the dates in closing_date table, you follow ?
I hope my explanation is clear.....
Let me know guys..if you can do me a little query ?
thanks alot EE.
I need to do a SQL Query.
I have a table called Closing_Date
in this table, the columns are: Date, Description
For example, values can be :
07/01/2020 Canada Day
07/10/2020 Summer vacation
07/11/2020 Summer Vacation
07/12/2020 Summer Vacation
......
12/25/2020 Christmas
etc..
in another table, let's call it TABLE_A i have 4 columns :
JobNo, JobDate, NbDays, DeliveryDate
values for example can be :
001, 04/11/2019, 68, 02/01/2020
002 04/15/2020, 56, 08/01/2020
003, 05/05/2020, 68, 08/01/2020
My question is, and maybe you already see me coming with this question :
I need to get a "ResultDate" that will grab for a JobNo, the JobDate and add the NbDays to it and see if I go beyond the DelieveryDate. but WITHOUT counting the days in the Table Closing_Date.
so if we add 68 days to the JobDate, and it goes beyond 08/01/2020, well maybe its not true if we remove the dates in closing_date table, you follow ?
I hope my explanation is clear.....
Let me know guys..if you can do me a little query ?
thanks alot EE.
I would recommend implementing a true Calendar table and have a boolean column to indicate whether you are closed are not. It saves a step. Below is a possible solution that hopefully will help out.
DECLARE @Closing_Date TABLE
(
[Date] DATE NOT NULL,
[Description] VARCHAR(500) NOT NULL
);
INSERT @Closing_Date
(
[Date],
[Description]
)
VALUES
('20200101', 'New Years Day'),
('20200704', 'Independence Day'),
('20200701', 'Canada Day'),
('20200710', 'Closed'),
('20200711', 'Closed'),
('20200712', 'Closed'),
('20201224', 'Christmas Eve'),
('20201225', 'Christmas Day');
DECLARE @TableA TABLE
(
JobNo INT NOT NULL,
JobDate DATE NOT NULL,
NBDays INT NOT NULL,
DeliveryDate DATE NULL
);
INSERT @TableA
(
JobNo,
JobDate,
NBDays,
DeliveryDate
)
VALUES
(1, '04/11/2019', 68, '02/01/2020'),
(2, '04/15/2020', 56, '08/01/2020'),
(3, '05/05/2020', 68, '08/01/2020');
WITH cteCalendar AS
(
SELECT CAST('20190101' AS DATE) AS [Date]
UNION ALL
SELECT DATEADD(DAY, 1, [Date])
FROM cteCalendar
WHERE [Date] < '20211231'
),
cteClosedCalendar AS
(
SELECT C.[Date],
CASE WHEN CD.[Date] IS NOT NULL THEN 1 ELSE 0 END AS IsClosed
FROM cteCalendar AS C
LEFT OUTER JOIN @Closing_Date AS CD
ON C.[Date] = CD.[Date]
),
cteJobCalendar AS
(
SELECT Job.JobNo,
Job.JobDate,
Job.NBDays,
Job.DeliveryDate,
C.[Date] AS CalendarDate,
C.Isclosed,
ROW_NUMBER() OVER(PARTITION BY Job.JobNo, C.IsClosed ORDER BY C.[Date]) AS DateRowNumber
FROM @TableA AS Job
INNER JOIN cteClosedCalendar AS C
ON Job.JobDate < C.[Date]
)
SELECT cteJobCalendar.JobNo,
cteJobCalendar.JobDate,
cteJobCalendar.NBDays,
cteJobCalendar.DeliveryDate,
cteJobCalendar.CalendarDate AS ResultDate,
DATEADD(DAY, cteJobCalendar.NBDays, cteJobCalendar.JobDate) AS CalcResultDate
FROM cteJobCalendar
WHERE cteJobCalendar.IsClosed = 0
AND cteJobCalendar.DateRowNumber = cteJobCalendar.NBDays
ORDER BY cteJobCalendar.CalendarDate
OPTION (MAXRECURSION 0);
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Creating Tables:
USE Dict
GO
CREATE TABLE Closing_Date ([Date] Date, [Description] NVarChar(200))
GO
CREATE TABLE TABLE_A(JobNo VarChar(3), JobDate Date, NbDays Int, DeliveryDate Date)
GO
INSERT INTO Closing_Date([Date],[Descr iption]) VALUES
('07/01/2020', 'Canada Day'),
('07/10/2020', 'Summer vacation'),
('07/11/2020', 'Summer Vacation'),
('07/12/2020', 'Summer Vacation')
GO
INSERT INTO TABLE_A(JobNo, JobDate, NbDays, DeliveryDate) VALUES
('001', '04/11/2019', 68, '02/01/2020'),
('002', '04/15/2020', 56, '08/01/2020'),
('003', '05/05/2020', 68, '06/01/2020') -- It was changed for test
GO
SELECT * FROM Closing_Date
SELECT * FROM TABLE_A
GO
Calculating:
USE Dict
GO
DECLARE @JobNo VarChar(3), @JobDate Date, @NbDays Int,
@DeliveryDate Date, @CurrentDay Int, @FinishDate Date,
@WorkDays Int
DECLARE cr CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT * FROM TABLE_A
OPEN cr
WHILE 1=1 BEGIN
FETCH NEXT FROM cr INTO @JobNo, @JobDate, @NbDays, @DeliveryDate
IF @@FETCH_STATUS <> 0 BREAK
SET @CurrentDay = 0
SET @WorkDays = 0
WHILE @WorkDays < @NbDays BEGIN
IF NOT Exists(
SELECT NULL FROM Closing_Date
WHERE [Date] = DateAdd(day, @CurrentDay, @JobDate)
) BEGIN
SET @WorkDays += 1
END
SET @CurrentDay += 1
END
SET @FinishDate = DateAdd(day, @CurrentDay, @JobDate)
PRINT 'The job No: ['+@JobNo+']'
PRINT '@JobDate = ' + Cast(@JobDate AS NVarChar)
PRINT '@CurrentDay = ' + Cast(@CurrentDay AS NVarChar)
PRINT '@WorkDays = ' + Cast(@WorkDays AS NVarChar)
PRINT '@DeliveryDate = ' + Cast(@DeliveryDate AS NVarChar)
PRINT '@FinishDate = ' + Cast(@FinishDate AS NVarChar)
IF @FinishDate > @DeliveryDate BEGIN
PRINT 'The job ['+@JobNo+'] will be finished after the Delivery Date:'
END
PRINT ' '
END
CLOSE cr
DEALLOCATE cr
Results:
The job No: [001]
@JobDate = 2019-04-11
@CurrentDay = 68
@WorkDays = 68
@DeliveryDate = 2020-02-01
@FinishDate = 2019-06-18
The job No: [002]
@JobDate = 2020-04-15
@CurrentDay = 56
@WorkDays = 56
@DeliveryDate = 2020-08-01
@FinishDate = 2020-06-10
The job No: [003]
@JobDate = 2020-05-05
@CurrentDay = 72
@WorkDays = 68
@DeliveryDate = 2020-06-01
@FinishDate = 2020-07-16
The job [003] will be finished after the Delivery Date:
USE Dict
GO
CREATE TABLE Closing_Date ([Date] Date, [Description] NVarChar(200))
GO
CREATE TABLE TABLE_A(JobNo VarChar(3), JobDate Date, NbDays Int, DeliveryDate Date)
GO
INSERT INTO Closing_Date([Date],[Descr
('07/01/2020', 'Canada Day'),
('07/10/2020', 'Summer vacation'),
('07/11/2020', 'Summer Vacation'),
('07/12/2020', 'Summer Vacation')
GO
INSERT INTO TABLE_A(JobNo, JobDate, NbDays, DeliveryDate) VALUES
('001', '04/11/2019', 68, '02/01/2020'),
('002', '04/15/2020', 56, '08/01/2020'),
('003', '05/05/2020', 68, '06/01/2020') -- It was changed for test
GO
SELECT * FROM Closing_Date
SELECT * FROM TABLE_A
GO
Calculating:
USE Dict
GO
DECLARE @JobNo VarChar(3), @JobDate Date, @NbDays Int,
@DeliveryDate Date, @CurrentDay Int, @FinishDate Date,
@WorkDays Int
DECLARE cr CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT * FROM TABLE_A
OPEN cr
WHILE 1=1 BEGIN
FETCH NEXT FROM cr INTO @JobNo, @JobDate, @NbDays, @DeliveryDate
IF @@FETCH_STATUS <> 0 BREAK
SET @CurrentDay = 0
SET @WorkDays = 0
WHILE @WorkDays < @NbDays BEGIN
IF NOT Exists(
SELECT NULL FROM Closing_Date
WHERE [Date] = DateAdd(day, @CurrentDay, @JobDate)
) BEGIN
SET @WorkDays += 1
END
SET @CurrentDay += 1
END
SET @FinishDate = DateAdd(day, @CurrentDay, @JobDate)
PRINT 'The job No: ['+@JobNo+']'
PRINT '@JobDate = ' + Cast(@JobDate AS NVarChar)
PRINT '@CurrentDay = ' + Cast(@CurrentDay AS NVarChar)
PRINT '@WorkDays = ' + Cast(@WorkDays AS NVarChar)
PRINT '@DeliveryDate = ' + Cast(@DeliveryDate AS NVarChar)
PRINT '@FinishDate = ' + Cast(@FinishDate AS NVarChar)
IF @FinishDate > @DeliveryDate BEGIN
PRINT 'The job ['+@JobNo+'] will be finished after the Delivery Date:'
END
PRINT ' '
END
CLOSE cr
DEALLOCATE cr
Results:
The job No: [001]
@JobDate = 2019-04-11
@CurrentDay = 68
@WorkDays = 68
@DeliveryDate = 2020-02-01
@FinishDate = 2019-06-18
The job No: [002]
@JobDate = 2020-04-15
@CurrentDay = 56
@WorkDays = 56
@DeliveryDate = 2020-08-01
@FinishDate = 2020-06-10
The job No: [003]
@JobDate = 2020-05-05
@CurrentDay = 72
@WorkDays = 68
@DeliveryDate = 2020-06-01
@FinishDate = 2020-07-16
The job [003] will be finished after the Delivery Date:
Personally I wouldn't use procedural code when you can meet requirements with straight SQL.
ASKER
Thank you guys, let me see all the answers, sorry for delay. i will come back
If you can post expected results with the sample data you posted, we can post tested SQL.
ASKER
Scott I had some problems to understand your Cross apply with the select TOP
got some errors
got some errors
I did test it. Please let know the specific error(s) you are getting. The syntax I used should be valid from SQL 2005 on.
ASKER
hey guys, need your help here : https://www.experts-exchange.com/questions/29194894/Running-averages-in-a-select-query.html
Please try this:
Open in new window