March 29, 2017 at 12:03 pm
Hi, from the sample code below, I am trying to get all the records from the 3 most recent dates, I thought by using " with ties" it would match the last result found based on the value in the "ORDER BY" . I was expecting to bring all rows from 28, 27 and 24. Any help on how I can do that? Thank you!
create table mytable (account_id int, event_time datetime, sign char(3));
insert into mytable values
(2251,'2017-03-28 19:00:04','YES')
,(2250,'2017-03-28 15:45:11','NO')
,(2250,'2017-03-28 01:01:45','NO')
,(2250,'2017-03-27 15:45:11','YES')
,(2250,'2017-03-27 01:01:45','NO')
,(2249,'2017-03-24 21:00:03','YES')
,(2248,'2017-03-24 05:45:10','NO')
,(2247,'2017-03-19 21:00:05','YES')
,(2246,'2017-03-19 05:45:10','NO')
,(2245,'2017-03-22 21:15:05','YES')
select top 3 with ties
account_id
, event_time
, sign
from mytable
order by convert(date,event_time) desc
March 29, 2017 at 12:12 pm
a_car11 - Wednesday, March 29, 2017 12:03 PMHi, from the sample code below, I am trying to get all the records from the 3 most recent dates, I thought by using " with ties" it would match the last result found based on the value in the "ORDER BY" . I was expecting to bring all rows from 28, 27 and 24. Any help on how I can do that? Thank you!
create table mytable (account_id int, event_time datetime, sign char(3));
insert into mytable values
(2251,'2017-03-28 19:00:04','YES')
,(2250,'2017-03-28 15:45:11','NO')
,(2250,'2017-03-28 01:01:45','NO')
,(2250,'2017-03-27 15:45:11','YES')
,(2250,'2017-03-27 01:01:45','NO')
,(2249,'2017-03-24 21:00:03','YES')
,(2248,'2017-03-24 05:45:10','NO')
,(2247,'2017-03-19 21:00:05','YES')
,(2246,'2017-03-19 05:45:10','NO')
,(2245,'2017-03-22 21:15:05','YES')select top 3 with ties
account_id
, event_time
, sign
from mytable
order by convert(date,event_time) desc
Try this and let me know if this works for you:create table mytable (account_id int, event_time datetime, sign char(3));
insert into mytable values
(2251,'2017-03-28 19:00:04','YES')
,(2250,'2017-03-28 15:45:11','NO')
,(2250,'2017-03-28 01:01:45','NO')
,(2250,'2017-03-27 15:45:11','YES')
,(2250,'2017-03-27 01:01:45','NO')
,(2249,'2017-03-24 21:00:03','YES')
,(2248,'2017-03-24 05:45:10','NO')
,(2247,'2017-03-19 21:00:05','YES')
,(2246,'2017-03-19 05:45:10','NO')
,(2245,'2017-03-22 21:15:05','YES');
with top_dates as (
select top 3 with ties convert(date,event_time) as event_date
from mytable
order by convert(date,event_time) desc
)
select
account_id,
event_time,
sign
from mytable as mt
INNER JOIN top_dates as td
ON convert(date, mt.event_time) = td.event_date
order by mt.event_time desc;
drop table mytable;
Steve (aka sgmunson) 🙂 🙂 🙂
Rent Servers for Income (picks and shovels strategy)
March 29, 2017 at 12:21 pm
This is what I get:
account_id | event_time | sign | |
---|---|---|---|
1 | 2251 | 28.03.2017 19:00:04 | YES |
2 | 2251 | 28.03.2017 19:00:04 | YES |
3 | 2251 | 28.03.2017 19:00:04 | YES |
4 | 2250 | 28.03.2017 15:45:11 | NO |
5 | 2250 | 28.03.2017 15:45:11 | NO |
6 | 2250 | 28.03.2017 15:45:11 | NO |
7 | 2250 | 28.03.2017 01:01:45 | NO |
8 | 2250 | 28.03.2017 01:01:45 | NO |
9 | 2250 | 28.03.2017 01:01:45 | NO |
March 29, 2017 at 12:25 pm
Use a CTE with DENSE_RANK().
;
WITH mytable_dr AS
(
SELECT account_id, event_time, [sign],
DENSE_RANK() OVER(ORDER BY CAST(event_time AS DATE) DESC) AS dr
FROM #mytable
)
SELECT account_id, event_time, [sign]
FROM mytable_dr
WHERE dr <= 3
Drew
J. Drew Allen
Business Intelligence Analyst
Philadelphia, PA
March 29, 2017 at 12:29 pm
a_car11 - Wednesday, March 29, 2017 12:21 PMThis is what I get:
account_id event_time sign 1 2251 28.03.2017 19:00:04 YES 2 2251 28.03.2017 19:00:04 YES 3 2251 28.03.2017 19:00:04 YES 4 2250 28.03.2017 15:45:11 NO 5 2250 28.03.2017 15:45:11 NO 6 2250 28.03.2017 15:45:11 NO 7 2250 28.03.2017 01:01:45 NO 8 2250 28.03.2017 01:01:45 NO 9 2250 28.03.2017 01:01:45 NO
That's what I get as well. Is it correct?
Steve (aka sgmunson) 🙂 🙂 🙂
Rent Servers for Income (picks and shovels strategy)
March 29, 2017 at 12:34 pm
sgmunson - Wednesday, March 29, 2017 12:29 PMThat's what I get as well. Is it correct?
No, this is what it should get:
account_id | event_time | sign | |
---|---|---|---|
1 | 2251 | 28.03.2017 19:00:04 | YES |
2 | 2250 | 28.03.2017 15:45:11 | NO |
3 | 2250 | 28.03.2017 01:01:45 | NO |
4 | 2250 | 27.03.2017 15:45:11 | YES |
5 | 2250 | 27.03.2017 01:01:45 | NO |
6 | 2249 | 24.03.2017 21:00:03 | YES |
7 | 2248 | 24.03.2017 05:45:10 | NO |
March 29, 2017 at 12:43 pm
drew.allen - Wednesday, March 29, 2017 12:25 PMUse a CTE with DENSE_RANK().
;
WITH mytable_dr AS
(
SELECT account_id, event_time, [sign],
DENSE_RANK() OVER(ORDER BY CAST(event_time AS DATE) DESC) AS dr
FROM #mytable
)
SELECT account_id, event_time, [sign]
FROM mytable_dr
WHERE dr <= 3Drew
Need to research on "DENSE_RANK()", but it works. Thank you!
March 29, 2017 at 12:47 pm
to fix Steve's, the CTE query needs a DISTINCT in it otherwise it returns 2017-03-28 3 times:
with top_dates as (
select DISTINCT top 3 with ties convert(date,event_time) as event_date
from mytable
order by convert(date,event_time) desc
)
select
account_id,
event_time,
sign
from mytable as mt
INNER JOIN top_dates as td
ON convert(date, mt.event_time) = td.event_date
order by mt.event_time desc;
that produces the proper results. The DENSE_RANK one looks like it might be more efficient execution plan though
March 29, 2017 at 12:48 pm
TOP(n) WITH TIES is closer to RANK() rather than DENSE_RANK(). This is the reason that both queries that use TOP(n) WITH TIES don't give the desired results. To see this, I've commented out one of the records in the sample to produce a situation where there are records that match the ties.
create table #mytable (account_id int, event_time datetime, sign char(3));
insert into #mytable values
(2251,'2017-03-28 19:00:04','YES')
,(2250,'2017-03-28 15:45:11','NO')
--,(2250,'2017-03-28 01:01:45','NO')
,(2250,'2017-03-27 15:45:11','YES')
,(2250,'2017-03-27 01:01:45','NO')
,(2249,'2017-03-24 21:00:03','YES')
,(2248,'2017-03-24 05:45:10','NO')
,(2247,'2017-03-19 21:00:05','YES')
,(2246,'2017-03-19 05:45:10','NO')
,(2245,'2017-03-22 21:15:05','YES')
SELECT *,
RANK() OVER(ORDER BY CAST(event_time AS DATE) DESC),
DENSE_RANK() OVER(ORDER BY CAST(event_time AS DATE) DESC)
FROM #mytable
WITH TIES will pull all records with the specified RANK(), but you want the records with the specified DENSE_RANK().
Drew
J. Drew Allen
Business Intelligence Analyst
Philadelphia, PA
March 29, 2017 at 1:13 pm
a_car11 - Wednesday, March 29, 2017 12:34 PMsgmunson - Wednesday, March 29, 2017 12:29 PMThat's what I get as well. Is it correct?
No, this is what it should get:
account_id event_time sign 1 2251 28.03.2017 19:00:04 YES 2 2250 28.03.2017 15:45:11 NO 3 2250 28.03.2017 01:01:45 NO 4 2250 27.03.2017 15:45:11 YES 5 2250 27.03.2017 01:01:45 NO 6 2249 24.03.2017 21:00:03 YES 7 2248 24.03.2017 05:45:10 NO
Oops! Here's a corrected version, which will not need the "with ties" option:create table mytable (account_id int, event_time datetime, sign char(3));
insert into mytable values
(2251,'2017-03-28 19:00:04','YES')
,(2250,'2017-03-28 15:45:11','NO')
,(2250,'2017-03-28 01:01:45','NO')
,(2250,'2017-03-27 15:45:11','YES')
,(2250,'2017-03-27 01:01:45','NO')
,(2249,'2017-03-24 21:00:03','YES')
,(2248,'2017-03-24 05:45:10','NO')
,(2247,'2017-03-19 21:00:05','YES')
,(2246,'2017-03-19 05:45:10','NO')
,(2245,'2017-03-22 21:15:05','YES');
with top_dates as (
select top (3) event_date
FROM (
select distinct convert(date,event_time) as event_date
from mytable
) AS X
order by event_date desc
)
select
account_id,
event_time,
sign
from mytable as mt
INNER JOIN top_dates as td
ON convert(date, mt.event_time) = td.event_date
order by mt.event_time desc;
drop table mytable;
Steve (aka sgmunson) 🙂 🙂 🙂
Rent Servers for Income (picks and shovels strategy)
March 29, 2017 at 1:52 pm
a_car11 - Wednesday, March 29, 2017 12:43 PMdrew.allen - Wednesday, March 29, 2017 12:25 PMUse a CTE with DENSE_RANK().
;
WITH mytable_dr AS
(
SELECT account_id, event_time, [sign],
DENSE_RANK() OVER(ORDER BY CAST(event_time AS DATE) DESC) AS dr
FROM #mytable
)
SELECT account_id, event_time, [sign]
FROM mytable_dr
WHERE dr <= 3Drew
Need to research on "DENSE_RANK()", but it works. Thank you!
An "order by account_id" in the end is needed otherwise the latest time will get out of order
Viewing 11 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic. Login to reply