2016-01-28 64 views
0

我想計算兩個TIME之間的差異(扣除),它們都保存在一個表中,但在不同的行和列中也是如此。我在NT INTEL X86平臺上使用SQL Server 2008 R2 Express(版本10.50.2500.0)。SQL Server:從屬子查詢

我一樣有這樣一個表:

CREATE TABLE TBL_DATA 
(
    id INT IDENTITY(1,1) PRIMARY KEY,     
    opid INT, 
    lotid INT,      
    dt_date DATE, 
    dt_begin_test TIME, 
    dt_end_test TIME 
); 

該表加載數據/例如:

id  opid lotid dt_date  dt_begin_test  dt_end_test 
---------------------------------------------------------------------- 
5800 352 13381 2016-01-27 08:17:18.0000000 08:17:40.0000000 
5801 352 13381 2016-01-27 08:17:49.0000000 08:18:11.0000000 
5802 352 13381 2016-01-27 08:18:18.0000000 08:18:40.0000000 
5803 319 13381 2016-01-27 08:18:11.0000000 08:18:33.0000000 
5804 352 13381 2016-01-27 08:18:48.0000000 08:19:10.0000000 
5805 352 13381 2016-01-27 08:19:18.0000000 08:19:39.0000000 
5806 319 13381 2016-01-27 08:18:59.0000000 08:19:21.0000000 
5807 352 13381 2016-01-27 08:19:47.0000000 08:20:09.0000000 
5808 352 13381 2016-01-27 08:20:16.0000000 08:20:38.0000000 
5809 319 13381 2016-01-27 08:19:59.0000000 08:20:21.0000000 
5810 352 13381 2016-01-27 08:20:45.0000000 08:21:07.0000000 
5811 352 13381 2016-01-27 08:21:14.0000000 08:21:36.0000000 
5812 319 13381 2016-01-27 08:20:50.0000000 08:21:12.0000000 
5813 352 13381 2016-01-27 08:21:43.0000000 08:22:05.0000000 
5814 319 13381 2016-01-27 08:21:27.0000000 08:21:49.0000000 
5815 352 13381 2016-01-27 08:22:12.0000000 08:22:33.0000000 
5816 319 13381 2016-01-27 08:22:04.0000000 08:22:26.0000000 
5817 352 13381 2016-01-27 08:22:41.0000000 08:23:02.0000000 

我想獲得對用戶輸出與opid=352,例如,在我需要從dt_end_test行的的值中扣除行5805的值dt_begin_test。結果應該是8 seconds。並使其與opid=352的所有用戶線一致。

在表TBL_DATA中只有一個opid值的情況下,有一個非常漂亮的解決方案。

SELECT TBL_TEST.id, 
     TBL_TEST.opid, 
     TBL_TEST.lotid,   
     TBL_TEST.dt_date, 
     TBL_TEST.dt_begin_test, 
     TBL_TEST.dt_end_test,  
     COALESCE(
      DATEDIFF(
        second, (
        SELECT TBL_TMP.dt_end_test 
        FROM [TBL_DATA] AS TBL_TMP 
        WHERE TBL_TMP.id = TBL_TEST.id - 1),     
        TBL_TEST.dt_begin_test), 0) AS PAR_DEDUCT 
FROM [TBL_DATA] AS TBL_TEST 

不幸的是,如果您必須從不是一個接一個的行中扣除值,則此解決方案會失敗。

的情況下我:

SELECT TBL_TEST.id, 
     TBL_TEST.opid, 
     TBL_TEST.lotid,   
     TBL_TEST.dt_date, 
     TBL_TEST.dt_begin_test, 
     TBL_TEST.dt_end_test,  
     COALESCE(
      DATEDIFF(
        second, (
        SELECT TBL_TMP.dt_end_test 
        FROM [TBL_DATA] AS TBL_TMP 
        WHERE TBL_TMP.id = TBL_TEST.id - 1),     
        TBL_TEST.dt_begin_test), 0) AS PAR_DEDUCT 
FROM [TBL_DATA] AS TBL_TEST 
WHERE opid=352; 

不正確我是這麼理解的工作。

爲此,我有一個想法,我將使用row_number()函數來創建一個新的列,然後使用另一個選擇來做到這一點。略微修改SELECT查詢如下:

SELECT *, 
COALESCE(DATEDIFF(second, 
     (SELECT dt_end_test FROM TBL_A AS TBL_TMP WHERE TBL_A.PAR_INDEX = TBL_TMP.PAR_INDEX - 1), 
       TBL_A.dt_begin_test), 0) AS PAR_DEDUCT 
FROM 
(SELECT row_number() OVER (ORDER BY TBL_TEST.id) AS PAR_INDEX, 
    TBL_TEST.id, 
    TBL_TEST.opid, 
    TBL_TEST.lotid, 
    TBL_TEST.dt_date, 
    TBL_TEST.dt_begin_test, 
    TBL_TEST.dt_end_test 
FROM [TBL_DATA] AS TBL_TEST 
WHERE opid=352 
) AS TBL_A; 

不幸的是,它不起作用。它在DATEDIFF ... SELECT聲明中的TBL_A參數有問題。

我可以用另一種方法做到這一點。我可以將結果保存在一張臨時表格中,然後按照上述方式進行操作。我想要的是在一個執行/命令中執行它。

任何幫助非常感謝。

Tomas。

回答

0

您可能可以在cte中使用Row_number執行所需操作,並將它連接到自身。

;WITH cte AS (
    SELECT *, 
      ROW_NUMBER() OVER (PARTITION BY opid,lotid ORDER BY dt_date, dt_begin_test) Rn 
    FROM TBL_DATA 
) 
SELECT t1.*, 
     DATEDIFF(SECOND,t2.dt_end_test,t1.dt_begin_test) 
FROM cte t1 
     LEFT JOIN cte t2 ON t1.opid = t2.opid 
          AND t1.lotid = t2.lotid 
          AND t1.Rn - 1 = t2.Rn 
ORDER BY t1.opid, 
     t1.lotid, 
     t1.dt_date, 
     t1.dt_begin_test 
+0

非常感謝您的幫助。稍作修改後,它解決了我的問題! – Miky