我有一个像这样的表结构:
name idletime speed RJ14 300 0 RJ14 360 0 RJ14 400 0 RJ14 0 30 RJ14 50 0 VJ23 100 0 VJ23 160 0 VJ23 200 0 VJ23 0 50 VJ23 30 0
我想要这种格式的结果
name idletime RJ14 400 RJ14 50 VJ23 200 VJ23 30
我需要一个查询,只要另一个字段(速度)的值为零,就可以返回字段的最大值。有什么建议?感谢。
修改
当特定名称的速度大于零时,idletime
变为零。我需要在每次变为零之前的空闲时间值。
我已经尝试过此查询,但它没有返回预期的结果。
SELECT NAME ,MAX(idleTime) FROM idletime WHERE speed=0 GROUP BY NAME
答案 0 :(得分:3)
当特定
speed
的{{1}}大于零时,name
变为零。我需要idletime
的值,然后每次都变为零。每一行都有唯一的ID
<强>查询强>
idletime
<强> SQL fiddle 强>
工作原理
首先,我们创建一个添加;WITH numberedidletable AS
(
SELECT id,name,idletime,speed,
ROW_NUMBER() OVER (ORDER BY name,id) AS RN
FROM idletable
)
SELECT name,idletime
FROM numberedidletable
WHERE speed = 0 AND
RN IN (
(SELECT RN-1
FROM numberedidletable tmpnit
WHERE speed<>0 AND
numberedidletable.name = tmpnit.name)
UNION ALL
(SELECT MAX(RN)
FROM numberedidletable
GROUP BY name)
)
ORDER BY RN
的表格(因为我们无法保证唯一ID是顺序的):
ROW_NUMBER()
然后,我们得到行号(;WITH numberedidletable AS
(
SELECT id,name,idletime,speed,
ROW_NUMBER() OVER (ORDER BY name,id) AS RN
FROM idletable
)
),其中下一行有RN
:
speed <> 0
并且,每个 (SELECT RN-1
FROM numberedidletable tmpnit
WHERE speed<>0 AND
numberedidletable.name = tmpnit.name)
的最后一项的所有行号:
name
最后选择这些行号的所需列:
UNION ALL
(SELECT MAX(RN)
FROM numberedidletable
GROUP BY name)
<强>假设强>
SELECT name,idletime
FROM numberedidletable
WHERE speed = 0 AND
RN IN (
...
)
ORDER BY RN
是每个部分的增量。idletime
是唯一ID <强>输出强>
id
<强> SQL fiddle 强>
答案 1 :(得分:2)
那么你想要所有按ID排序的最大空闲记录以及之后没有非空闲记录的所有记录吗?
这比我想象的要复杂得多。您可以使用多个CTE来简化它:
WITH CTE AS
(
SELECT ID, Name, IdleTime, Speed,
RN = ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ID ASC)
FROM dbo.TableName t
)
, Idles AS
(
SELECT ID, Name, IdleTime, Speed, RN
FROM CTE
WHERE Speed = 0 AND IdleTime <> 0
)
, NonIdles AS
(
SELECT ID, Name, IdleTime, Speed, RN
FROM CTE
WHERE Speed <> 0 AND IdleTime = 0
)
SELECT ID, Name, IdleTime, Speed
FROM Idles i
WHERE NOT EXISTS
(
SELECT 1 FROM Idles i2
WHERE i.Name = i2.Name AND i2.RN > i.RN
)
OR EXISTS
(
SELECT 1 FROM NonIdles ni
WHERE i.Name = ni.Name AND i.RN + 1 = ni.RN
)
带有示例数据的
答案 2 :(得分:2)
我为此问题尝试了一种程序化方法。它为我解决了。下面的查询选择速度= 0时的最大空闲时间和速度从非零值再次变为0的第一个空闲时间值。
Create table stack (id varchar(5), id1 int, id2 int)
INSERT INTO STACK
VALUES
('RJ14' , 300 , 0 ),
('RJ14' , 360 , 0 ),
('RJ14' , 400 , 0 ),
('RJ14' , 0 , 30 ),
('RJ14' , 50 , 0 ),
('VJ23' , 100 , 0 ),
('VJ23' , 160 , 0 ),
('VJ23' , 200 , 0 ),
('VJ23' , 0 , 50 ),
('VJ23' , 30 , 0 )
declare @stack as table (name varchar(5),idletime int, id2 int, rws int)
declare @val as table (name varchar(5),idletime int )
insert into @stack
SELECT ID,ID1 idletime, id2, row_number() over(order by id ) as rws
FROM STACK
declare @id int = 1
declare @count int
declare @value int = 0
select @count = count (*) from @stack
while (@id <= @count)
begin
select @value = ID2 from @stack where rws = @id and id2 <> 0
if @value <> 0
begin
insert into @val
select name, idletime
from @stack
where rws = @id -1
union
select name, idletime from
@stack where rws = @id + 1
end
select @id = @id + 1
select @value = 0
end
select *from @val ORDER BY NAME, idletime DESC
这是相同的SQL-FIDDLE