将Excel公式转换为SQL查询

7

这是一个Excel文件,我可以使用公式来获取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))))

这是我在Excel中用来获取TAT ORIG值的公式。

我需要将相同的公式转换或者找到一个方法,在现有的SQL表中获取相同的值,该表的列名为tat_orig

在这个表中,我需要使用SQL查询计算tat_orig

enter image description here


1
我们需要更多的上下文。很少有人会花时间来剖析那个Excel公式。您可以使用尽可能多的单词。此外,您没有提供TAT ORIG是什么。只需解释如何满足条件以获得最终结果即可。 - S3S
1
我强烈建议尝试拆分Excel公式...你不想最终得到嵌套在彼此中的众多CASE语句 - 这基本上就是Excel公式“IF(A,1,IF(B,2,IF...)”会导致的情况。 - Tyron78
1
你尝试过用SQL写吗?我认为大多数人不会只为你编写查询。 - Kyle
更新table1 SET table1.tat_orig = CONVERT(VARCHAR, DATEDIFF(Hour, time_created, time_responded) % 24) + '.' + CONVERT(VARCHAR, DATEDIFF(minute, time_created, time_responded) % 100) 这是我用SQL获取等待时间的方法... 我想让别人帮我构建一个查询,计算周转时间(tat_orig)。我已经上传了在Excel中准确计算我所需内容的公式,但我需要SQL查询,请帮忙。 - Raj JAdhav
感谢 @thor2k,爱你兄弟,请帮帮我。 - Raj JAdhav
显示剩余4条评论
1个回答

6

哇,我没想到这需要这么长时间。以下是我的翻译:

--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;

困难在于计算日期。您不必声明函数-它们存在于其中以清晰地计算中间值,但从技术上讲,您应该能够在SELECT语句中使用返回值。
顺便说一句,如果您的计算列正在从下一行中获取值,则运气不佳-这在SQL中不是不可能,但几乎无法实现。
希望这可以帮助您!
编辑:
我添加了日期差异大支架。我添加了一年测试数据。
--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;

我尝试了这个... 更新dbo.FinalExtract 从dbo.FinalExtract设置tat_orig = dbo.TURNAROUND(time_created,time_responded) 但是我得到了错误: Msg 535, Level 16, State 0, Line 2 datediff函数导致溢出。两个日期/时间实例之间分隔的日期部分数量太大。尝试使用较不精确的日期部分进行datediff。 该语句已终止。 - Raj JAdhav
谢谢。您可以使用方程式在T-SQL中定义计算列,例如 [Name] = [First] + ' ' + [Last];当然,在您的情况下,计算可能更加复杂,但这并不意味着它不能内联。关于溢出问题,请尝试将日期差分规范从毫秒(ms)降低到秒--我只是默认使用最高可用精度。 - hector-j-rivas
请提供失败的数据--以文本格式--以便我能够重现此问题。 - hector-j-rivas
兄弟,请回来,我需要你的帮助。 - Raj JAdhav
仍然无法解决...我还有其他问题,@thor2k你知道我想要什么...你能上线帮助我吗? - Raj JAdhav
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接