How to fetch records with lastest 2 version numbers - sql

How to fetch records with latest 2 version numbers from a table using SQL query.
I want to fetch user ids for a tracking id for the last 2 versions.
Below is my table description:
TRACKING_ID ,
User_id,
Version_number
Below query gives me the user id having the latest version.
Select user_id
from table t1
join
(select tracking_id,max(version_number) as version_number
from table
group by tracking_id ) t2
on t1.tracking_id=t2.tracking_id
and t1.version_number=t2.version_number
Appreciate your response.

You can use ROW_NUMBER:
SELECT tracking_id,
user_id,
version_number
FROM ( SELECT *,
ROW_NUMBER() OVER(PARTITION BY tracking_id ORDER BY version_number DESC) AS RN
FROM YourTable) AS T
WHERE RN <= 2

I don't fully understand the question but something like this may point you in the correct direction.
WITH CTE AS (
SELECT tracking_ID, user_ID, version_number,
Row_number() over (partition by USER_ID, Version_number desc) as RN)
SELECT *
FROM cte
WHERE RN <= 2;
I'm not sure if the user_ID or the tracking_ID needs to be partitioned...

Related

Display Prev and Current value based on a ID - SQL

I am not sure if a similar question has been posted. I was unable to find one.
I have the following table:
What I trying to get is the below:
Any advice will be appreciated.
Thanks in advance,
Sam
Worked both in Oracle and Snowflake:
SELECT t.ID,
t.prev_dt,
t.current_dt,
t.prev_code,
t.curr_code
FROM (
SELECT id,
order_dt,
LAG(order_dt, 1) OVER (PARTITION by id ORDER BY id, order_dt) prev_dt,
upd_dt current_dt,
LAG(code, 1) OVER (PARTITION by id ORDER BY id, upd_dt) prev_code,
code curr_code
FROM t111
) t
INNER JOIN (
SELECT id,
MAX(order_dt) max_date
FROM t111
GROUP BY id
) idm
ON idm.id=t.id AND t.order_dt=idm.max_date
You seem to want window function lag():
select
id,
lag(order_dt) over(partition by id order by order_by_id) prev_dt,
order_dt current_dt,
lag(code) over(partition by id order by order_by_id) prev_code,
code curr_code
from mytable
Note that the above query does not filter the records of the table. When there is no preceeding record, lag() returns null. If you want to filter out the first record per group, and assuming that such record is identify by order_by_id = 1, you can do:
select *
from (
select
id,
lag(order_dt) over(partition by id order by order_by_id) prev_dt,
order_dt current_dt,
lag(code) over(partition by id order by order_by_id) prev_code,
code curr_code,
order_by_id
from mytable
) t
where order_by_id > 1
Window functions might be the best approach. But you could also use join:
select t1.id, t1.order_dt as prev_dt, t2.upd_dt as curr_date,
t1.code as prev_code, t2.code as curr_code
from t t1 join
t t2
on t1.id = t2.id and t1.order_by_id = 1 and t2.order_by_id = 2;
In Snowflake, I simply do not know whether this would have better, worse, or similar performance to using window functions.

Get latest record from a table based on 2 columns in hive

I want to get the latest record from my source table based on num and id columns and insert in my target table.
Scenario is explained in the attached screen shot. For latest record date column can be used.
Screenshot
Thanks.
Select num,id, date
FROM
(
Select *, ROW_NUMBER() OVER(partition by num,id Order by date desc) as rnk
FROM source_table
)a
WHERE rnk = 1;
by using corelated Subquery
select * from your_table t
where t.date= (
select max(date) from your_table t1
where t1.num=t.num and t1.id=t.id
)
You can do it using max() function
select num,id,max(date) from your_table t
group by num,id
SELECT NUM,ID,DATE FROM TABLE_TEMP
QUALIFY RANK OVER(PARTITION BY NUM,ID ORDER BY DATE DESC)=1;
You can do this using single line query
SELECT NUM,ID,DATE FROM TABLE_TEMP
QUALIFY RANK OVER(PARTITION BY NUM,ID ORDER BY DATE DESC)=1;

Sql query to fetch second latest entry from a table

I have a table with below mentioned columns. I want to fetch the previous status of customer. Once customer id can have multiple entries
Customer_id status start_date end_date Active
1 Member 01-JAN-18 04-FEB-18 N
1 Explorist 05-FEB-18 30-APR-18 N
1 Globalist 01-MAY-18 31-DEC-99 Y
Desired output
Customer _id Previous_status end_date
1 Explorist 30-APR-18
Please try below query using QUALIFY keyword and ROW_NUMBER():
SELECT a.* from table a
QUALIFY ROW_NUMBER OVER(PARTITION BY customer_id order by start_date desc) = 2
Below query should work.
SELECT * from (
SELECT a.*,
ROW_NUMBER() over (partition by customer_id order by start_date desc) rn
from table a )
where rn =2
You can use below query and I guess that is very simple and that worked for me,
select * from customer order by end_date desc limit 1,1
Consider this question: Select Nth Row From A Table In Oracle
In your case, that would be:
select * from (select a.*, rownum rnum from (select * from <your table name>
order by <start_date or end_date> desc) a where rownum <= 2) where rnum >= 2;
If you are using Oracle DataBase then try below query using ROW_NUMBER() function:Let's consider the table name is customer
SELECT TEMP.CUSTOMER_ID
,TEMP.STATUS
,TEMP.START_DATE
,TEMP.END_DATE
,TEMP.ACTIVE
FROM(
SELECT ROW_NUMBER() OVER (PARTITION BY CUSTOMER_ID ORDER BY CUSTOMER_ID ASC,START_DATE DESC) AS "ROW_NUM"
,CUSTOMER_ID
,STATUS
,START_DATE
,END_DATE
,ACTIVE
FROM CUSTOMER) TEMP
WHERE TEMP."ROW_NUM" = 2;

How to Select Top 100 rows in Oracle?

My requirement is to get each client's latest order, and then get top 100 records.
I wrote one query as below to get latest orders for each client. Internal query works fine. But I don't know how to get first 100 based on the results.
SELECT * FROM (
SELECT id, client_id, ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn
FROM order
) WHERE rn=1
Any ideas? Thanks.
Assuming that create_time contains the time the order was created, and you want the 100 clients with the latest orders, you can:
add the create_time in your innermost query
order the results of your outer query by the create_time desc
add an outermost query that filters the first 100 rows using ROWNUM
Query:
SELECT * FROM (
SELECT * FROM (
SELECT
id,
client_id,
create_time,
ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn
FROM order
)
WHERE rn=1
ORDER BY create_time desc
) WHERE rownum <= 100
UPDATE for Oracle 12c
With release 12.1, Oracle introduced "real" Top-N queries. Using the new FETCH FIRST... syntax, you can also use:
SELECT * FROM (
SELECT
id,
client_id,
create_time,
ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn
FROM order
)
WHERE rn = 1
ORDER BY create_time desc
FETCH FIRST 100 ROWS ONLY)
you should use rownum in oracle to do what you seek
where rownum <= 100
see also those answers to help you
limit in oracle
select top in oracle
select top in oracle 2
As Moneer Kamal said, you can do that simply:
SELECT id, client_id FROM order
WHERE rownum <= 100
ORDER BY create_time DESC;
Notice that the ordering is done after getting the 100 row. This might be useful for who does not want ordering.
Update:
To use order by with rownum you have to write something like this:
SELECT * from (SELECT id, client_id FROM order ORDER BY create_time DESC) WHERE rownum <= 100;
First 10 customers inserted into db (table customers):
select * from customers where customer_id <=
(select min(customer_id)+10 from customers)
Last 10 customers inserted into db (table customers):
select * from customers where customer_id >=
(select max(customer_id)-10 from customers)
Hope this helps....
To select top n rows updated recently
SELECT *
FROM (
SELECT *
FROM table
ORDER BY UpdateDateTime DESC
)
WHERE ROWNUM < 101;
Try this:
SELECT *
FROM (SELECT * FROM (
SELECT
id,
client_id,
create_time,
ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn
FROM order
)
WHERE rn=1
ORDER BY create_time desc) alias_name
WHERE rownum <= 100
ORDER BY rownum;
Or TOP:
SELECT TOP 2 * FROM Customers; //But not supported in Oracle
NOTE: I suppose that your internal query is fine. Please share your output of this.

How to select distinct records based on condition

I have table of duplicate records like
Now I want only one record from duplicate records which has latest created date as How can I do it ?
use row_number():
select EnquiryId, Name, . . .
from (select t.*,
row_number() over (partition by enquiryID order by CreatedDate desc) as seqnum
from table t
) t
where seqnum = 1;
Use ROW_NUMBER function to tag the duplicate records ordered by CreatedDate, like this:
;with CTE AS (
select *, row_NUMBER() over(
partition by EnquiryID -- add columns on which you want to identify duplicates
ORDER BY CreatedDate DESC) as rn
FROM TABLE
)
select * from CTE
where rn = 1