查询SQL Server 2005

时间:2014-02-14 03:23:30

标签: sql sql-server

我有一张时间和里程标记表:

08:00 101.2
08:45 109.8
09:15 109.8
09:30 111.0
10:00 114.6

我需要看起来像这样的输出:

08:00-08:45 101.1-109.8
08:45-09:15 109.8-109.8
09:15-09:30 109.8-111.0
09:30-10:00 111.0-114.6

我想我需要2个相同的记录集,并以某种方式将第一个记录与另一个的第二个记录联系起来,但对如何完成该记录(或如何提出问题)一无所知。任何帮助将不胜感激。

提前致谢, 金妮

4 个答案:

答案 0 :(得分:2)

以下查询将获得下一个值:

select tm.*,
       (select top 1 time
        from timemilemarkers tm2
        where tm2.time > tm.time
        order by 1 desc
       ) as nexttime,
       (select top 1 milemarker
        from timemilemarkers tm2
        where tm2.time > tm.time
        order by 1 desc
       ) as nextmilemarker
from timemilemarkers tm;

您可以使用以下内容将它们放入所需的表单中:

select concat_ws('-', milemarker, nextmilemarker), concat_ws('-', time, nexttime)
from (select tm.*,
             (select top 1 time
              from timemilemarkers tm2
              where tm2.time > tm.time
              order by 1 desc
             ) as nexttime,
             (select top 1 milemarker
              from timemilemarkers tm2
              where tm2.time > tm.time
              order by 1 desc
             ) as nextmilemarker
      from timemilemarkers tm
     ) tm
where nextmilemarker is not null;

答案 1 :(得分:1)

其他方法是:

SQLFiddle

select cast(A.TIME_COL as varchar) + ' - ' + cast(B.TIME_COL as varchar), 
    cast(A.MILES as varchar) + ' - ' +  cast(B.MILES as varchar)
from (select row_number() OVER (order by time_col) ID, * from TABLE_A) A 
inner join (select row_number() OVER (order by time_col) ID, * from TABLE_A) B
    on A.ID = B.ID - 1

更新:此查询仅适用于SQL Server 2008及更高版本,显然无法回答您的问题。我不会抹掉答案,因为它可以对其他人有所帮助。

UPDATE2 :适用于SQL Server 2005

答案 2 :(得分:0)

试试这个,

Declare @t table (times  time(0), milemarkers  decimal(5,2))

insert into @t
select '08:00','101.2' union all
select'08:45','109.8' union all
select'09:15','109.8' union all
select'09:30','111.0' union all
select'10:00','114.6'

;With cte1 as
(select *,ROW_NUMBER()over(order by times)rn from @t
)
,cte2 as
(select max(rn) rn1 from cte1)
, cte as
(select 
(select times from cte1 where rn=1)lowerlimit,(select times from cte1 where rn=2)upperlimit,
(select milemarkers from cte1 where rn=1)lowerlimit1,(select milemarkers from cte1 where rn=2)upperlimit1
,1 rn  from cte1
union all
select upperlimit,(select times from cte1 where rn=a.rn+2) 
,upperlimit1,(select milemarkers from cte1 where rn=a.rn+2)
,rn+1
 from cte a where a.rn<(select rn1  from cte2)
) 

select distinct cast(lowerlimit as varchar(10))+'-'+cast(upperlimit as varchar(10)) ,
cast(lowerlimit1 as varchar(10))+'-'+cast(upperlimit1 as varchar(10))
from cte a where a.rn<(select rn1  from cte2)

答案 3 :(得分:0)

使用CTE我们可以获得OutPut它也可以通过其他方式查找以下查询

DECLARE  @TABLE_A  table(time_col time, miles float)

insert into @TABLE_A values ('08:00',101.2)
insert into @TABLE_A values ('08:45',109.8)
insert into @TABLE_A values ('09:15',109.8)
insert into @TABLE_A values ('09:30',111.0)
insert into @TABLE_A values ('10:00',114.6)

;WITH CTE  AS
(
SELECT t.time_col,t.miles,t.RN FROM 
(
Select ROW_NUMBER()OVER(ORDER BY time_col )RN,* FRom @TABLE_A 
)t
INNER JOIN (
Select ROW_NUMBER()OVER(ORDER BY time_col )RN,* FRom @TABLE_A 
)tt 
ON t.RN = tt.RN 
)
,CTE2(TimeSpan,Miles) AS
(
Select CONVERT(VARCHAR,c.time_col,108) +'-'+ 
(Select CONVERT(VARCHAR,time_col,108) FROM CTE WHERE RN = cc.RN + 1) As TimeSpan,
 CAST(c.miles AS VARCHAR) +' - '+ (Select CAST(miles AS VARCHAR) FROM CTE WHERE RN = CC.RN + 1)AS Miles  FROM CTE c
INNER JOIN CTE CC
ON CC.miles = c.miles
AND CC.time_col = c.time_col
)
Select TimeSpan,Miles from CTE2
WHERE TimeSpan IS NOT NULL