此问题与SQL Server有关。我有下表:
id size batch code product code additiontime
--------------------------------------------------------
1 91 55555 BigD Red 2017-05-15 13:00:00
2 91 55555 BigD Red 2017-05-15 13:00:05
3 94 55555 BigD Red 2017-05-15 13:00:15
4 91 44444 BigD Blue 2017-05-15 14:10:00
5 92 44444 BigD Blue 2017-05-15 14:15:00
6 93 44444 BigD Blue 2017-05-15 14:20:00
7 94 44444 BigD Blue 2017-05-15 14:30:00
8 91 33333 BigD Orange 2017-05-15 15:00:00
9 91 33333 BigD Orange 2017-05-15 15:00:10
10 94 33333 BigD Orange 2017-05-15 15:00:15
执行此SQL语句时:
select *
from mytable y1
where size = 91
and not exists (select 1
from mytable y2
where y1.productcode = y2.productcode and y2.size = 92)
我得到以下结果:
id size batch code product code additiontime
--------------------------------------------------------
1 91 55555 BigD Red 2017-05-15 13:00:00
2 91 55555 BigD Red 2017-05-15 13:00:05
8 91 33333 BigD Orange 2017-05-15 15:00:00
9 91 33333 BigD Orange 2017-05-15 15:00:10
我想修改上面的查询,以便每个批次代码显示一行,并添加一个额外的列以显示每个批次代码组的第一个和第二个记录之间的秒数差异,例如:
id size batch code product code additiontime seconds difference
--------------------------------------------------------------------------------------
1 91 55555 BigD Red 2017-05-15 13:00:00 5
8 91 33333 BigD Orange 2017-05-15 15:00:00 10
我尝试过以下SQL,它几乎可以解决这个问题,但它会返回多行,而不是每批代码只返回一行:
WITH rows AS
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY AdditionTime) AS rn
FROM
mytable y1
WHERE
size = 91
AND NOT EXISTS (SELECT *
FROM mytable y2
WHERE y1.productcode = y2.productcode AND y2.size = 92)
)
SELECT DATEDIFF(second, mc.AdditionTime, mp.AdditionTime)
FROM rows mc
JOIN rows mp ON mc.rn = mp.rn - 1
我的SQL知识不是很好。我确信它可以产生正确的结果,但我已经尝试了所有方法但没有成功。提前感谢任何指针。
答案 0 :(得分:2)
这为您提供了所需的输出,并在cte的结果上进行了自联接。另外,我在PARTITION BY
添加了ROW_NUMBER()
:
CREATE TABLE #mytable
(
id INT ,
size INT ,
batchCode INT ,
productCode NVARCHAR(30) ,
additiontime DATETIME
);
INSERT INTO #mytable
( id, size, batchCode, productCode, additiontime )
VALUES ( 1, 91, 55555, 'BigD Red', '2017-05-15 13:00:00' ),
( 2, 91, 55555, 'BigD Red', '2017-05-15 13:00:05' ),
( 3, 94, 55555, 'BigD Red', '2017-05-15 13:00:15' ),
( 4, 91, 44444, 'BigD Blue', '2017-05-15 14:10:00' ),
( 5, 92, 44444, 'BigD Blue', '2017-05-15 14:15:00' ),
( 6, 93, 44444, 'BigD Blue', '2017-05-15 14:20:00' ),
( 7, 94, 44444, 'BigD Blue', '2017-05-15 14:30:00' ),
( 8, 91, 33333, 'BigD Orange', '2017-05-15 15:00:00' ),
( 9, 91, 33333, 'BigD Orange', '2017-05-15 15:00:10' ),
( 10, 94, 33333, 'BigD Orange', '2017-05-15 15:00:15' );
WITH rows
AS ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY y1.batchCode ORDER BY additiontime ) AS rn
FROM #mytable y1
WHERE size = 91
AND NOT EXISTS ( SELECT *
FROM #mytable y2
WHERE y1.productCode = y2.productCode
AND y2.size = 92 )
)
SELECT t1.id ,
t1.size ,
t1.batchCode ,
t1.productCode ,
DATEDIFF(SECOND, t1.additiontime, t2.additiontime) SecondsDiff
FROM rows t1
INNER JOIN rows t2 ON t2.batchCode = t1.batchCode
AND t1.id != t2.id
WHERE t1.rn = 1;
DROP TABLE #mytable
<强>产地:强>
id size batchCode productCode SecondsDiff
8 91 33333 BigD Orange 10
1 91 55555 BigD Red 5
注意,您应该使用更大的数据集进行测试,以确保准确性并考虑其他任何情况。
答案 1 :(得分:1)
你其实非常接近! :)
唯一缺少的是在JOIN
的{{1}}上添加另一个条件,以便您只比较具有相同CTE
的行,如下所示:
product code
PS。假设您知道每个产品有两行。
答案 2 :(得分:1)
;With cte(id,size,batchcode,productcode,additiontime)
AS
(
SELECT 1 , 91, 55555,'BigD Red' ,'2017-05-15 13:00:00' UNION ALL
SELECT 2 , 91, 55555,'BigD Red' ,'2017-05-15 13:00:05' UNION ALL
SELECT 3 , 94, 55555,'BigD Red' ,'2017-05-15 13:00:15' UNION ALL
SELECT 4 , 91, 44444,'BigD Blue' ,'2017-05-15 14:10:00' UNION ALL
SELECT 5 , 92, 44444,'BigD Blue' ,'2017-05-15 14:15:00' UNION ALL
SELECT 6 , 93, 44444,'BigD Blue' ,'2017-05-15 14:20:00' UNION ALL
SELECT 7 , 94, 44444,'BigD Blue' ,'2017-05-15 14:30:00' UNION ALL
SELECT 8 , 91, 33333,'BigD Orange','2017-05-15 15:00:00' UNION ALL
SELECT 9 , 91, 33333,'BigD Orange','2017-05-15 15:00:10' UNION ALL
SELECT 10, 94, 33333,'BigD Orange','2017-05-15 15:00:15'
)
SELECT id
,size
,batchcode
,productcode
,additiontime
,(SecondDiff - LEADadditiontimeSec) AS secondsDifference
FROM (
SELECT *
,DATEPART(SECOND, additiontime) LEADadditiontimeSec
,DATEPART(SECOND, LEADadditiontime) SecondDiff
FROM (
SELECT *
,LEAD(additiontime) OVER (
PARTITION BY batchcode
,size ORDER BY batchcode
) LEADadditiontime
FROM cte o
WHERE size = 91
AND NOT EXISTS ( SELECT * FROM cte i
WHERE o.productCode = i.productCode
AND i.size = 92 )
) Dt
) Final
WHERE Final.SecondDiff IS NOT NULL
ORDER BY 1
输出
id size batchcode productcode additiontime secondsDifference
------------------------------------------------------------------------------
1 91 55555 BigD Red 2017-05-15 13:00:00 5
8 91 33333 BigD Orange 2017-05-15 15:00:00 10
答案 3 :(得分:0)
希望以下查询能为您完成这项工作 -
SELECT id, size, [batch code], [product code], additiontime, DATEDIFF(SECOND, additiontime, next_addition_time) AS [seconds difference]
FROM
(
SELECT *
, LEAD(additiontime) OVER (PARTITION BY [batch code] ORDER BY additiontime) AS next_addition_time
, ROW_NUMBER() OVER (PARTITION BY [batch code] ORDER BY additiontime) AS row_num
FROM mytable
) AS t
WHERE row_num = 1;
首先,子查询按每个批次的添加时间排序行号。它还存储下一个添加时间值。然后,外部查询只选择第一行以及当前和下一个添加时间之间的差异。
请注意,如果数据很大,您应该将子查询移动到临时表。您也可以执行 ORDER BY 并在where子句中提供过滤器。