2017-06-20 237 views
1

這是我的第一個問題。SQL - 如何比較不同行中的兩列?

如何在不同的線路比較兩列?該數據庫是SQL Server 2000中

我在我的表中的這些數據:

id   entrance    exit 
----------- ----------------------- ----------------------- 
10000  2017-06-03 09:07:00.000 NULL 
10000  NULL     2017-06-03 11:59:00.000 
10000  NULL     2017-06-03 12:31:00.000 
10000  2017-06-03 12:25:00.000 NULL 
20000  2017-06-03 13:13:00.000 NULL 
20000  NULL     2017-06-03 17:39:00.000 

我需要驗證的入口和出口之間的差異。

例如:第一次入口(第一行)和第一次出口(第二行)之間的差異,在比較之後,驗證第一次出口(第二行)和下一次入口(第三行)等等。

我如何比較這幾行?謝謝!

+0

對不起,我沒有告訴,數據庫是SQL 2000 –

+3

停止一切你在做什麼,並升級到支持的版本。只是一些建議。這是4年前結束的生命支持。 – scsimon

+0

數據庫中沒有「行」。除非您指定要訂購的內容,否則該數據將被視爲無序。你有沒有可靠的排序欄(例如最後更新,或標識欄)? –

回答

0

你需要製造一個行ID的確切順序。

CREATE TABLE #temp 
(RowId INT IDENTITY(1,1) 
, Id INT 
, Entrance DATETIME 
, [Exit] DATETIME 
) 
INSERT #temp VALUES(10000 , '2017-06-03 09:07:00.000', NULL) 
INSERT #temp VALUES(10000 , NULL, '2017-06-03 11:59:00.000') 
INSERT #temp VALUES(10000 , NULL ,'2017-06-03 12:31:00.000') 
INSERT #temp VALUES(10000 , '2017-06-03 12:25:00.000', NULL) 
INSERT #temp VALUES(20000 , '2017-06-03 13:13:00.000', NULL) 
INSERT #temp VALUES(20000 , NULL ,'2017-06-03 17:39:00.000') 

SELECT a.RowId 
    , a.id 
    , ISNULL(a.entrance, a.[exit]) AS Entrance 
    , ISNULL(b.[exit], b.Entrance) AS [Exit] 
FROM #temp a 
LEFT JOIN #temp b 
    ON b.Id = a.Id 
    AND b.RowId = a.RowId + 1 
0

這是真的,每行包含任何入口或出口?如果是,那麼我的建議就是將這些列合併爲一個並使用一個標誌。你可以考慮使用UNION來達到這個目的。

現在您可以編寫一個從第1行到最後一行運行的小程序,並查找連續行之間的差異。

+0

在原始數據中,我有入口和出口在一起。我有一個標誌描述是否入口'E',如果是退出'S'。 –

+0

我認爲最好是寫一個程序。 – MKR

+0

我認爲最好是寫一個程序。按ID,日期時間,列(最新的第一個)排序。循環遍歷第一行到最後一行。從頂部的行中的當前行減去日期時間(如果它們具有不同的類型'E'或'S')。你可以生成一個包含id,日期,時間差的數組。 – MKR

0

如果可能的話當ID已經存在,你可以做一個「更新」查詢。這裏的id不是唯一可識別的。

https://www.w3schools.com/sql/sql_update.asp

,然後你可以選擇:

select t.exit - t.entrance as difference from table t where t.id="2000" 

如果它仍然需要每次插入新行,然後生成一個行ID SQL期間由溫迪另一個答案建議。

0

我會建議使用下面的代碼。這個想法是選擇所有具有非空條目值的行(en),然後將其與具有相同ID但具有大於條目時間戳(,例如)的退出時間戳的記錄結合。最後,左連接(xex)用於確保沒有其他具有在enex之間的退出時間戳的行。

-- data stored as per original question 
CREATE TABLE #tbl 
(
    [id] INT NOT NULL, 
    [entrance] DATETIME, 
    [exit] DATETIME 
); 

INSERT INTO #tbl ([id], [entrance], [exit]) 
VALUES (10000, '2017-06-03 09:07:00.000', NULL); 
INSERT INTO #tbl ([id], [entrance], [exit]) 
VALUES (10000, NULL, '2017-06-03 11:59:00.000'); 
INSERT INTO #tbl ([id], [entrance], [exit]) 
VALUES (10000, NULL, '2017-06-03 12:31:00.000'); 
INSERT INTO #tbl ([id], [entrance], [exit]) 
VALUES (10000, '2017-06-03 12:25:00.000', NULL); 
INSERT INTO #tbl ([id], [entrance], [exit]) 
VALUES (20000, '2017-06-03 13:13:00.000', NULL); 
INSERT INTO #tbl ([id], [entrance], [exit]) 
VALUES (20000, NULL, '2017-06-03 17:39:00.000'); 

SELECT en.id, en.[entrance], ex.[exit], 
DATEDIFF(MINUTE, en.[entrance], ex.[exit]) elapsed_min 
FROM #tbl en 
JOIN #tbl ex ON en.id=ex.id AND ex.[exit] IS NOT NULL AND ex.[exit] > en.[entrance] 
LEFT JOIN #tbl xex ON en.id=xex.id AND xex.[exit] IS NOT NULL 
AND xex.[exit] < ex.[exit] AND xex.[exit] > en.[entrance] 
WHERE en.entrance IS NOT NULL AND xex.[id] IS NULL; 


GO 

-- data stored as per comment 
CREATE TABLE #tbl2 
(
    [id] INT NOT NULL, 
    [type] CHAR(1) NOT NULL, 
    [timestamp] DATETIME NOT NULL 
); 

INSERT INTO #tbl2 ([id], [type], [timestamp]) 
VALUES (10000, 'E', '2017-06-03 09:07:00.000'); 
INSERT INTO #tbl2 ([id], [type], [timestamp]) 
VALUES (10000, 'S', '2017-06-03 11:59:00.000'); 
INSERT INTO #tbl2 ([id], [type], [timestamp]) 
VALUES (10000, 'S', '2017-06-03 12:31:00.000'); 
INSERT INTO #tbl2 ([id], [type], [timestamp]) 
VALUES (10000, 'E', '2017-06-03 12:25:00.000'); 
INSERT INTO #tbl2 ([id], [type], [timestamp]) 
VALUES (20000, 'E', '2017-06-03 13:13:00.000'); 
INSERT INTO #tbl2 ([id], [type], [timestamp]) 
VALUES (20000, 'S', '2017-06-03 17:39:00.000'); 

SELECT en.id, en.[timestamp], ex.[timestamp], 
DATEDIFF(MINUTE, en.[timestamp], ex.[timestamp]) elapsed_min 
FROM #tbl2 en 
JOIN #tbl2 ex ON en.id=ex.id AND ex.[type]='S' AND ex.[timestamp] > en.[timestamp] 
LEFT JOIN #tbl2 xex ON en.id=xex.id AND xex.[type]='S' 
AND xex.[timestamp] < ex.[timestamp] AND xex.[timestamp] > en.[timestamp] 
WHERE en.[type]='E' AND xex.[id] IS NULL; 

GO