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.