SQL - 如何比较不同行中的两列?

时间:2017-06-20 20:27:29

标签: sql sql-server

这是我的第一个问题。

如何比较不同行中的两列?该数据库是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 

我需要验证入口和出口之间的区别。

例如:在此比较之后,第一个入口(第一行)和第一个出口(第二行)之间的差异在第一个出口(第二行)和下一个入口(第三行)之间进行验证,依此类推。

我如何比较这些线?谢谢!

4 个答案:

答案 0 :(得分:0)

每行都包含入口还是出口?如果是,那么我的建议是将这些列合并为一个并使用标志。您可以考虑将UNION用于此目的。

现在,您可以编写一个小程序,从第1行到最后一行运行,找到连续行之间的差异。

答案 1 :(得分: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

答案 2 :(得分: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" 

如果仍然需要每次都插入一个新行,那么在SQL期间生成一个行id,如Wendy在另一个答案中所建议的那样。

答案 3 :(得分:0)

我建议使用以下代码。我们的想法是选择具有非空条目值的所有行( en ),然后将其与具有相同ID但具有大于条目时间戳( ex )的退出时间的记录连接起来。最后,左连接( xex )用于确保 en ex 之间没有其他行具有退出时间戳。

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