tsql在每个组的第一行显示值

时间:2018-12-11 10:09:53

标签: sql-server tsql

假设我有两个表,一个是旅行,另一个是金额表。

旅行表格的下面各列

TripStartDateTime datetime
TripEndTime datetime
DriverId int

金额表包含这些列

TripStartDateTime datetime
TripEndDateTime datetime
DriverId int
Amount numeric(8,2)

我可以通过对金额表进行分组来获取每日总金额。

START_DATE  TOTAL_AMOUNT   DRIVER_ID
2018-11-12  6              112
2018-11-13  7              112

我想在每天的第一趟旅程中显示每日总金额,并在其余旅程中输入零或零。我已经尝试过交叉申请,但这样的旅行次数很多。

  START_DATE    START_TIME  END_TIME    AMOUNT    DRIVER_ID
    2018-11-12  09:19       09:44       6         112
    2018-11-12  09:57       10:16       6         112
    2018-11-12  08:57       09:16       6         112
    2018-11-13  13:23       13:42       7         112
    2018-11-13  13:52       13:57       7         112
    2018-11-13  12:52       12:57       7         112

是否可以联接这两个表并像这样显示?还是更好的编码方式?

  START_DATE    START_TIME  END_TIME    AMOUNT    DRIVER_ID
    2018-11-12  09:19       09:44       6         112
    2018-11-12  09:57       10:16       0         112
    2018-11-12  08:57       09:16       0         112
    2018-11-13  13:23       13:42       7         112
    2018-11-13  13:52       13:57       0         112
    2018-11-13  12:52       12:57       0         112

我知道这听起来很愚蠢,但是我不能使用真实表,所以我组成了类似的表结构。

我尝试过的sql查询

select 
    FORMAT(t.TripStartDateTime, 'yyyy-MM-dd') as START_DATE
    , FORMAT(t.TripStartDateTime, 'HH:mm') as START_TIME
    , FORMAT(t.TripEndTime, 'HH:mm') as END_TIME
    , unmatched.TOTAL_AMOUNT
    , t.DRIVER_ID
from trip t 
CROSS APPLY
(        
    select format(TripStartDateTime, 'yyy-MM-dd') as START_DATE, sum(Amount) TOTAL_AMOUNT, DRIVER_ID
    from Amount un 
    WHERE un.DRIVER_ID = t.DRIVER_ID

    group by format(TripStartDateTime, 'yyy-MM-dd'), DRIVER_ID
) unmatched 

where TripStartDateTime between @StartDt and @EndDate and t.DRIVER_ID = @DriverId

2 个答案:

答案 0 :(得分:0)

使用下面的逻辑

create table #temp
(TripStartDateTime datetime,TripEndDateTime datetime
,DriverId int,Amount numeric(8,2))

insert into #temp values('2018-11-12 09:19','2018-11-12 09:44',112,6)
insert into #temp values('2018-11-12 09:57','2018-11-12 10:16',112,6)
insert into #temp values('2018-11-12 08:57','2018-11-12 09:16',112,6)
insert into #temp values('2018-11-13 13:23','2018-11-12 13:43',112,7)
insert into #temp values('2018-11-13 13:52','2018-11-12 13:57',112,7)
insert into #temp values('2018-11-13 12:52','2018-11-12 12:57',112,7)

select 
    a.TripStartDateTime
    ,a.TripEndDateTime
    ,a.DriverId 
    ,case when a.seq>1 then 0 else sum(a.Amount)over(partition by cast(tripstartdatetime as date)) end as Amount
from
(
select 
    ROW_NUMBER()over(partition by amount order by TripStartDateTime ) as seq,* 
from #temp
)a

答案 1 :(得分:0)

您可以尝试使用以下代码,

create table #trip
(
    TripStartDateTime datetime,
    TripEndTime datetime,
    DriverId int
)

create table #amt
(
    TripStartDateTime datetime,
    TripEndDateTime datetime,
    DriverId int,
    Amount numeric(8,2)
)

insert into #trip
values ('2018-11-12 09:19', '2018-11-12 09:44', 112),
    ('2018-11-12  09:57', '2018-11-12 10:16', 112),
    ('2018-11-12  08:57', '2018-11-12 09:16', 112),
    ('2018-11-13  13:23', '2018-11-13 13:42' , 112),
    ('2018-11-13  13:52', '2018-11-13 13:57' ,112),
    ('2018-11-13  12:52', '2018-11-13 12:57' ,112),
    ('2018-11-12 09:19', '2018-11-12 09:44', 113),
    ('2018-11-12  09:57', '2018-11-12 10:16', 113),
    ('2018-11-12  08:57', '2018-11-12 09:16', 113),
    ('2018-11-13  13:23', '2018-11-13 13:42' , 113),
    ('2018-11-13  13:52', '2018-11-13 13:57' ,113),
    ('2018-11-13  12:52', '2018-11-13 12:57' ,113)

insert into #amt
values ('2018-11-12 09:19', '2018-11-12 09:44', 112, 6),
    ('2018-11-12  09:57', '2018-11-12 10:16', 112, 10),
    ('2018-11-12  08:57', '2018-11-12 09:16', 112, 12),
    ('2018-11-13  13:23', '2018-11-13 13:42' , 112, 13),
    ('2018-11-13  13:52', '2018-11-13 13:57' ,112, 14),
    ('2018-11-13  12:52', '2018-11-13 12:57' ,112, 15),
    ('2018-11-12 09:19', '2018-11-12 09:44', 113, 6),
    ('2018-11-12  09:57', '2018-11-12 10:16', 113, 10),
    ('2018-11-12  08:57', '2018-11-12 09:16', 113, 55),
    ('2018-11-13  13:23', '2018-11-13 13:42' , 113, 13),
    ('2018-11-13  13:52', '2018-11-13 13:57' ,113, 14),
    ('2018-11-13  12:52', '2018-11-13 12:57' ,113, 78)

;with cte (Start_Trip, DriverId)
as
(
    select distinct min(convert(varchar(10), TripStartDateTime, 108)), DriverId
    from #trip
    group by DriverId,convert(varchar(10), TripStartDateTime, 111)
)


select distinct
convert(varchar(10), t.TripStartDateTime, 111) as START_DATE,
convert(varchar(5), t.TripStartDateTime, 108) as START_TIME,
convert(varchar(5), t.TripEndTime, 108) as END_TIME,
case when c.Start_Trip is not null then a.Amount else 0 end,
t.DriverId
from #trip t
inner join #amt a
on a.DriverId = t.DriverId
and a.TripStartDateTime = t.TripStartDateTime
left outer join cte c
on c.DriverId = a.DriverId
and c.Start_Trip = convert(varchar(10), a.TripStartDateTime, 108)