2016-07-14 68 views
3

這是Excel文件,我可以用公式來獲得TAT ORIG轉換Excel公式到SQL查詢

enter image description here

=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

在此表中我需要tat_orig與SQL查詢來計算:

enter image description here

+1

我們需要更多的上下文。很少有人會花時間來剖析這個excel公式。根據需要使用盡可能多的單詞。你也沒有提供什麼是TAT ORIG。只要解釋什麼條件才能獲得最終結果。 – scsimon

+1

我強烈建議嘗試並分解excel公式......你不會想要結束嵌入對方的衆多CASE語句 - 這基本上是Excel的公式「IF(A,1,IF(B,2 ,IF ...「會導致 – Tyron78

+0

是的,我沒有確定CASE WHEN語句獲得期望的輸出結果.. –

回答

0

哇,我沒想到這這麼久。這裏是我得到的:

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

wooooh .....帽子給你兄弟...你真是天才和天生的傳奇......這是我需要的wat ...而且你做得像魅力...這正是我想要的,現在幫我一個小忙如何在我的現有表中實現此代碼與值已經存在於我的列time_Created,time_responded,這就是即時嘗試現在.... alter table dbo.FinalExtract add tat_orig浮 更新dbo.FinalExtract 組tat_orig = –

+0

我想這.... 更新dbo.FinalExtract 組tat_orig = dbo.TURNAROUND(TIME_CREATED,time_responded)從dbo.FinalExtract 但即時得到錯誤:消息535,第16級,狀態0,第2行 datediff函數導致溢出。分隔兩個日期/時間實例的日期部分數量太大。嘗試使用不精確的日期部分的datediff。 該聲明已被終止。 –

+0

謝謝。您可以使用方程定義T-SQL中的計算列,例如,[Name] = [First] +''+ [Last];當然在你的情況下,計算方式更復雜,但並不意味着它不能被內聯。關於溢出,嘗試從毫秒(ms)降低日期差異說明符到秒 - 我恰好默認爲可用的最高精度。 – thor2k