简体   繁体   中英

T-SQL get the last date time record

My table looks like this:

+---------+------------------------+-------+---------+---------+
|channel  |date                    |code   |comment  |order_id |
+---------+------------------------+-------+---------+---------+
|1        |2017-10-27 12:04:45.397 |2      |comm1    |1        |
|1        |2017-10-27 12:14:20.997 |1      |comm2    |1        |
|2        |2017-10-27 12:20:59.407 |3      |comm3    |1        |
|2        |2017-10-27 13:14:20.997 |1      |comm4    |1        |
|3        |2017-10-27 12:20:59.407 |2      |comm5    |1        |
|3        |2017-10-27 14:20:59.407 |1      |comm6    |1        |
+---------+------------------------+-------+---------+---------+

And I expect result like this:

+---------+------------------------+-------+---------+
|channel  |date                    |code   |comment  |
+---------+------------------------+-------+---------+
|1        |2017-10-27 12:14:20.997 |1      |comm2    |
|2        |2017-10-27 13:14:20.997 |1      |comm4    |
|3        |2017-10-27 14:20:59.407 |1      |comm6    |
+---------+------------------------+-------+---------+

Always 1 record with order_id = x and max date for each channel. Total number of channels is constant. My query works but I'm worried about performance as the table grows. Doing three almost identical queries doesn't seem smart.

select
    *
from
    (select top(1)
        channel,
        date,
        code,
        comment
    from
        status
    where
        channel = 1 and
        order_id = 1 and
        cast(date as date) = '2017-10-27'
    order by 
        date desc) channel1
union
select 
    *
from
    (select top(1)
        channel,
        date,
        code,
        comment
    from
        status
    where
        channel = 2 and
        order_id = 1 and
        cast(date as date) = '2017-10-27'
    order by 
        date desc) channel2
union
select 
    *
from
    (select top(1)
        channel,
        date,
        code,
        comment
    from
        status
    where
        channel = 3 and
        order_id = 1 and
        cast(date as date) = '2017-10-27'
    order by 
        date desc) channel3

How can I improve this?

Another option is using the WITH TIES clause. No sub-query or extra field.

Select top 1 with ties *
 From  YourTable
 Order By Row_Number() over (Partition By channel order by date desc)

Try using the ROW_NUMBER() function and a derived table. It will save you a lot of headaches. Try:

select channel
       ,date
       ,code
       ,comment
from
(select *
       ,row_number() over(partition by channel order by code asc) rn --probably don't need asc since it is ascending by default
from mytable) t
where t.rn = 1

Assuming you want the latest row for each channel, this would work.

SELECT *
FROM (
    SELECT
        ROW_NUMBER() OVER (PARTITION BY s.channel ORDER BY [date] DESC) AS rn,
        *
    FROM [status] AS s
) AS t
WHERE t.rn = 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM