Select Record with Maximum Creation Date - sql

Let us say that I have a database table with the following two records:
CACHE_ID BUSINESS_DATE CREATED_DATE
1183 13-09-06 13-09-19 16:38:59.336000000
1169 13-09-06 13-09-24 17:19:05.762000000
1152 13-09-06 13-09-17 14:18:59.336000000
1173 13-09-05 13-09-19 15:48:59.136000000
1139 13-09-05 13-09-24 12:59:05.263000000
1152 13-09-05 13-09-27 13:28:59.332000000
I need to write a query that will return the CACHE_ID for the record which has the most recent CREATED_DATE.
I am having trouble crafting such a query. I can do a GROUP BY based on BUSINESS_DATE and get the MAX(CREATED_DATE)...of course, I won't have the CACHE_ID of the record.
Could someone help with this?

Not positive on oracle syntax, but use the ROW_NUMBER() function:
SELECT BUSINESS_DATE, CACHE_ID
FROM (SELECT t.*,
ROW_NUMBER() OVER(PARTITION BY BUSINESS_DATE ORDER BY CREATED_DATE DESC) RN
FROM YourTable t
)sub
WHERE RN = 1
The ROW_NUMBER() function assigns a number to each row. PARTITION BY is optional, but used to start the numbering over for each value in that group,  ie: if you PARTITION BY BUSINESS_DATE  then for each unique BUSINESS_DATE value the numbering would start over at 1.  ORDER BY of course is used to define how the counting should go, and is required in the ROW_NUMBER() function.

You want to group on business date, and get the CACHE_ID with the most current created date? Use something like this:
select yt.CACHE_ID, yt.BUSINESS_DATE, yt.CREATED_DATE
from YourTable yt
where yt.CREATED_DATE = (select max(yt1.CREATED_DATE)
from YourTable yt1
where yt1.BUSINESS_DATE = yt.BUSINESS_DATE)

Not sure of the exact syntax, but conceptually, can't you just sort by CREATED_DATE descending and take the first one?

Across all records -
select top 1 CACHE_ID from YourTable order by CREATED_DATE desc
For each BUSINESS_DATE -
select distinct
a.BUSINESS_DATE,
(
select top 1 b.CACHE_ID
from YourTable b where a.BUSINESS_DATE = b.BUSINESS_DATE
order by b.CREATED_DATE desc
) as Last_CREATED_DATE
from YourTable a

Related

convert timestamp to date in hive and get data for that date

I have a query like this
select distinct emp,phno,addrs,email from cdv.emp;
Now I want to get only data which is created on the latest generated date and not old.
I have an audit column created_on - this is the unique key and Timestamp
select distinct emp,phno,addrs,email from cdv.emp;
I expect latest data based on created_on(timestamp) column which is generated in 24 hours or say the Max date
Use rank analytic function.It will work much faster than IN subquery:
select distinct emp,phno,addrs,email
from
(
select emp,phno,addrs,email,
rank() over(order by to_date(c.created_on) desc) rn
from cdv.emp c
)s
where rn=1;
If you want latest record per emp,phno,addrs,email, then you can use row_number() without distinct. If this method is applicable, this will be even faster:
select emp,phno,addrs,email
from
(
select emp,phno,addrs,email,
row_number() over(partition by emp,phno,addrs,email order by to_date(c.created_on) desc) rn
from cdv.emp c
)s
where rn=1;

how To Select with group by and order by clause?

I need to select from table by using group by clause and then order by clause
select id,EXID,Rate,Date,Currency from tb_exchange where Boolean='True' group by id,EXID,Rate,Date,Currency ORDER BY id DESC
But it return normally like
select * from tb_exchange where Boolean='True' ORDER BY id DESC
I need to return the newest item first and it groups by currency name. My Currency Name are (THB and USD )
Please help me,
thank in advance.
You may try using ROW_NUMBER here:
SELECT id, EXID, Rate, Date, Currency
FROM
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY Currency ORDER BY Date DESC) rn
FROM tb_exchange
WHERE Boolean = 'True'
) t
WHERE rn = 1
ORDER BY id DESC;
This answer assumes that you want the latest record from each Currency group and that the Date column records how recent or old a given record is.

SQL Earliest hour for every day

I have table like this
And I want to have only earliest time from column time for each day from column date. Rest of table has to be unaffected.
So result would be that for example that I have only time 9:25 for 2018-07-13 and rest of rows with later times for 2018-07-13 are deleted
To delete you can use a CTE with ROW_NUMBER window function
;WITH cteDups
AS(
SELECT *, RN=ROW_NUMBER()OVER (PARTITION BY M.Date ORDER BY M.Time ASC)
FROM dbo.yourtable M
)
--SELECT *
DELETE
FROM cteDups D WHERE D.RN > 1
You can use a window function to return all rows
select
*,
min([time]) over (partition by [date] order by [time])
from YourTable
Or just the aggregate to remove them
select *
from YourTable
inner join
(select whatever, min(FullDate) dt
from yourtable
group by whatever) x on x.whatever = YourTable.whatever and x.dt = YourTable.FullDate
If the whatever column doesn't matter, and you only want the date and time:
Select
[date],
min([time])
from YourTable
group by [Date]
The simplest way to keep certain records and remove the rest would be by using a CTE with a windowing function to rank (or add rownumbers). Check this out:
;WITH EarliestHourEveryDay AS (
SELECT
whatever
,FullDate
,[date]
,[time]
,rn = ROW_NUMBER() OVER (PARTITION BY [date] ORDER BY [time])
FROM TableName
)
SELECT *
FROM EarliestHourEveryDay
WHERE rn = 1
/*
DELETE FROM EarliestHourEveryDay
WHERE rn > 1
*/
I have commented out the delete statement so that you can test this first. Run the CTE as-is, and if the result set contains the exact rows which you want, remove the SELECT statement from the CTE and uncomment the DELETE statement and you'll be good to go.
Group by day and select the MIN time.
Use the MIN function and a GROUP BY clause.
Something like:
SELECT date, MIN(time) AS EarliestTime
FROM MyTable
GROUP BY date
ORDER BY date ASC
Here is an example of this working: SQL Fiddle

SQL SERVER QUERY to select max value record per item

This is the sample table
What I need to achieve is to get or display only the record of tenant with the highest month value. If ever month is equal, I need to base on the latest date value. Here is the sample desired output
With this, I started by this code using max function and incorporated temp table, but unable to get the desired result.
select tenant, name, date, month
into #sample
from tenant
select *
from #sample
where months = (select max(months)from #sample)
and output to something like this. As I believe, the code is getting the max value in the whole list not considering per tenant filtering.
Any help will be greatly appreciated :)
This can be done with the row_number window function:
select tenant, name, date, months
from (select t.*,
row_number() over (partition by t.tenant, t.name order by t.months desc, t.date desc) as rn
from TableName t) x
where rn = 1
You can use a row_number function.
Query
;with cte as
(
select rn = row_number() over
(
partition by tenant
order by months desc,[date] desc
),*
from table_name
)
select tenant,name,[date],months from cte
where rn = 1;

Limit result set in sql window function

Assume I would like to rewrite the following aggregate query
select id, max(hittime)
from status
group by id
using an aggregate windowing function like
select id, max(hittime) over(partition by id order by hittime desc) from status
How can I specify, that I am only interested in the first result within the partition?
EDIT: I was thinking that there might be a solution with [ RANGE | ROWS ] BETWEEN frame_start AND frame_end. What to get not only max(hittime) but also the second, third ...
I think what you need is a ranking function, either ROW_NUMBER or DENSE_RANK depending on how you want to handle ties.
select id, hittime
from (
select id, hittime,
dense_rank() over(partition by id order by hittime desc) as ranking
from status
) as x
where ranking = 1; --to get max hittime
--where ranking <=2; --max and second largest
Use distinct statement.
select DISTINCT id, max(hittime) over(partition by id order by hittime desc) from status