This is Excel file where I can Use formula to get TAT ORIG
:
=IF((X3-W3)*24<=24,(X3-W3)*24,
IF(AND(WEEKDAY(W3,2)<6,WEEKDAY(X3,2)<6),(NETWORKDAYS(W3,X3)-1+MOD(X3,1)-MOD(W3,1))*24,
IF(OR(WEEKDAY(W3,2)>5,WEEKDAY(X3,2)>5),(NETWORKDAYS(W3,X3)*24))))
this is the formula I used to get value for TAT ORIG
in EXCEL
I need same formula to be converted
or trick to get the same value in existing SQL table, with column name tat_orig
in this table I need tat_orig
to be calculated with SQL query:
Open an SQL connection to an Excel fileBefore running an SQL query, you have to open a connection with the Excel file you want to access. To establish the connection, create a new variable named %Excel_File_Path% and initialize it with the Excel file path.
Wow, I did not expect this to take so long. Here's what I've got:
--Network days shim
IF OBJECT_ID(N'NETWORKDAYS', N'FN') IS NOT NULL
DROP FUNCTION dbo.NETWORKDAYS;
GO
CREATE FUNCTION dbo.NETWORKDAYS(@d1 datetime, @d2 datetime )
RETURNS int
AS
BEGIN
DECLARE @w1 int = DATEPART(weekday, @d1);
DECLARE @w2 int = DATEPART(weekday, @d1);
DECLARE @dd float = FLOOR(DATEDIFF(ms, @d1, @d2) / 86400000.0);
-- network days is based on a holidays table; I just added this date arbitrarily so that
-- the results match what Excel says
DECLARE @holidays TABLE(holiday datetime);
INSERT INTO @holidays VALUES
('2016-06-15');
RETURN (@dd + @w2 - @w1) / 7 * 5 +
@w2 - @w1 + 1 +
IIF(@w2 = 7, -1, 0) +
IIF(@w1 = 1, -1, 0) +
(SELECT COUNT(*) FROM @holidays WHERE @d1 <= holiday AND holiday < @d2);
END
GO
-- turn around time shim
IF OBJECT_ID(N'TURNAROUND', N'FN') IS NOT NULL
DROP FUNCTION dbo.TURNAROUND;
GO
CREATE FUNCTION dbo.TURNAROUND(@d1 datetime, @d2 datetime)
RETURNS float
AS
BEGIN
DECLARE @w1 int = DATEPART(weekday, @d1);
DECLARE @w2 int = DATEPART(weekday, @d1);
DECLARE @nd int = dbo.NETWORKDAYS(@d1, @d2);
DECLARE @hd float = DATEDIFF(ms, @d1, @d2) / 3600000.0;
DECLARE @td float = DATEDIFF(ms, CAST(@d1 AS TIME), CAST(@d2 AS TIME)) / 86400000.0;
RETURN (
IIF(@hd <= 24.0,
@hd,
IIF(@w1 < 6 AND @w2 < 6,
24 * (@nd - 1 + @td),
IIF(@w2 > 5 OR @w1 > 5,
24 * @nd, 0))));
END
GO
-- the data
DECLARE @items TABLE
(
time_created datetime,
time_responded datetime
);
INSERT INTO @items VALUES
('2016-06-10 15:42:00.000', '2016-06-15 03:03:00.000'),
('2016-06-15 01:28:00.000', '2016-06-15 03:03:00.000'),
('2016-06-14 07:46:00.000', '2016-06-15 03:03:00.000'),
('2016-07-04 05:35:25.000', '2016-07-04 19:05:48.000'),
('2016-07-04 04:56:09.000', '2016-07-04 18:29:28.000'),
('2016-07-04 09:15:33.000', '2016-07-04 22:08:43.000'),
('2016-07-04 08:44:24.000', '2016-07-04 21:40:57.000'),
('2016-07-04 07:14:51.000', '2016-07-04 21:39:24.000');
-- the results
SELECT time_created, time_responded, dbo.TURNAROUND(time_created, time_responded) AS [TAT Orig] FROM @items;
The difficult part was figuring out the date arithmetic. You do not have to declare functions--they are there for clarity and calculating middle values, but technically you should be able to use the return values in a SELECT
statement.
BTW, you're out of luck if your computed column is taking values from the next row--it's not impossible in SQL, but it is close.
I hope this helps!
EDIT:
I added the date diff big shim. I added test data one year appart.
--Big datediff shim
IF OBJECT_ID(N'DATEDIFFBIG', N'FN') IS NOT NULL
DROP FUNCTION dbo.DATEDIFFBIG;
GO
CREATE FUNCTION DATEDIFFBIG(@d1 datetime, @d2 datetime)
RETURNS bigint
AS
BEGIN
RETURN CONVERT(bigint, DATEDIFF(day, @d1, @d2)) * 86400000 -
DATEDIFF(second, DATEADD(day, DATEDIFF(day, 0, @d1), 0), @d1) * 1000 +
DATEDIFF(second, DATEADD(day, DATEDIFF(day, 0, @d2), 0), @d2) * 1000;
END
GO
--Network days shim
IF OBJECT_ID(N'NETWORKDAYS', N'FN') IS NOT NULL
DROP FUNCTION dbo.NETWORKDAYS;
GO
CREATE FUNCTION dbo.NETWORKDAYS(@d1 datetime, @d2 datetime)
RETURNS int
AS
BEGIN
DECLARE @w1 int = DATEPART(weekday, @d1);
DECLARE @w2 int = DATEPART(weekday, @d1);
DECLARE @dd float = FLOOR(dbo.DATEDIFFBIG(@d1, @d2) / 86400000.0);
-- network days is based on a holidays table; I just added this date arbitrarily so that
-- the results match what Excel says
DECLARE @holidays TABLE(holiday datetime);
INSERT INTO @holidays VALUES
('2016-06-15');
RETURN (@dd + @w2 - @w1) / 7 * 5 +
@w2 - @w1 + 1 +
IIF(@w2 = 7, -1, 0) +
IIF(@w1 = 1, -1, 0) +
(SELECT COUNT(*) FROM @holidays WHERE @d1 <= holiday AND holiday < @d2);
END
GO
-- turn around time shim
IF OBJECT_ID(N'TURNAROUND', N'FN') IS NOT NULL
DROP FUNCTION dbo.TURNAROUND;
GO
CREATE FUNCTION dbo.TURNAROUND(@d1 datetime, @d2 datetime)
RETURNS float
AS
BEGIN
DECLARE @w1 int = DATEPART(weekday, @d1);
DECLARE @w2 int = DATEPART(weekday, @d1);
DECLARE @nd int = dbo.NETWORKDAYS(@d1, @d2);
DECLARE @hd float = dbo.DATEDIFFBIG(@d1, @d2) / 3600000.0;
DECLARE @td float = dbo.DATEDIFFBIG(CAST(@d1 AS TIME), CAST(@d2 AS TIME)) / 86400000.0;
RETURN (
IIF(@hd <= 24.0,
@hd,
IIF(@w1 < 6 AND @w2 < 6,
24 * (@nd - 1 + @td),
IIF(@w2 > 5 OR @w1 > 5,
24 * @nd, 0))));
END
GO
-- the data
DECLARE @items TABLE
(
time_created datetime,
time_responded datetime
);
INSERT INTO @items VALUES
('2016-06-10 15:42:00.000', '2016-06-15 03:03:00.000'),
('2016-06-15 01:28:00.000', '2016-06-15 03:03:00.000'),
('2016-06-14 07:46:00.000', '2016-06-15 03:03:00.000'),
('2016-07-04 05:35:25.000', '2016-07-04 19:05:48.000'),
('2016-07-04 04:56:09.000', '2016-07-04 18:29:28.000'),
('2016-07-04 09:15:33.000', '2016-07-04 22:08:43.000'),
('2016-07-04 08:44:24.000', '2016-07-04 21:40:57.000'),
('2016-07-04 07:14:51.000', '2016-07-04 21:39:24.000'),
('2015-07-04 07:14:51.000', '2016-07-04 21:39:24.000');
-- the results
SELECT time_created, time_responded, dbo.TURNAROUND(time_created, time_responded) AS [TAT Orig] FROM @items;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With