2017-06-20 232 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