我正在尝试计算两个TIME之间的差异(扣除),这两个TIME都保存在一个表中,但也存储在不同的行和列中。我在NT INTEL X86平台上使用SQL Server 2008 R2 Express(版本10.50.2500.0)。
我有一张像这样的桌子:
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_begin_test
行的值5805
中扣除dt_end_test
行5804
的值例如8 seconds
。结果应为opid=352
。并使用opid
为所有用户提供。
如果表TBL_DATA
中只有一个 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 *,
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;
函数创建一个新列,然后使用另一个选择来执行它。稍微修改SELECT查询如下:
TBL_A
不幸的是它不起作用。 DATEDIFF ... SELECT
语句中的{{1}}参数存在问题。
我可以用另一种方式做到。我可以将结果保存在临时表中,然后按照上面的说明进行操作。我想要的是在一个执行/命令中执行它。
非常感谢任何帮助。
托马斯。
答案 0 :(得分: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