SQL: select next available date for multiple records - sql

I have an oracle DB.
My table has ID and DATE columns (and more).
I would like to select for every ID the next available record after a certain date. For only one ID the query would be:
SELECT * FROM my_table
WHERE id = 1 AND date >= '01.01.2018'
(just ignoring the to_date() function)
How would that look like for multiple IDs? And I do want to SELECT *.
Thanks!

We can use ROW_NUMBER here:
SELECT ID, date -- and maybe other columns
FROM
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date) rn
FROM my_table
WHERE date >= date '2018-01-01'
) t
WHERE rn = 1
The idea here is to assign a row number to each ID partition, starting with the earliest date which occurs after the cutoff you specify. The first record from each partition would then be the immediate next date, assuming it exists.

Related

SQL Query to extract latest 2 dates from a column

A column consists of dates only. I need to extract the latest 2 dates from the table. What is the best way to do it?
Example: Values in a table having date column as 01-01-2021, 01-02-2021, 01-03-2021
I would need 01-02-2021,01-03-2021 as my output.
You can use rank() (or row_number() if there are no dupicliates):
select t.*
from t
qualify rank() over (order by datecol desc) <= 2;
Note: If you want distinct values, you could also use:
select distinct datecol
from t
order by datecol desc
limit 2;
You can order the column and then select the top X elements that you require
Select Top 2 col_Date
from MyTable
Order by col_Date DESC
The returned result would be a column
If you need to have a single string, there is a function that can help : STRING_SPLIT

How to get the latest 3 records of each group from dolphindb database?

My table name is trades, and its columns are permno, symbol, date, prc, shrout, ret, vol. I want to get the latest 3 records of each stock each date group. Does DolphinDB support such querying methods?
declare #trades as table
(
permno int,
symbol int,
groupdate date
)
insert into #trades(permno,symbol,groupdate)
values
(1,1,'2019-01-01'),
(2,2,'2019-01-01'),
(3,3,'2019-01-01'),
(4,4,'2019-01-01'),
(1,11,'2019-01-02'),
(2,22,'2019-01-02'),
(3,33,'2019-01-02'),
(4,44,'2019-01-02')
select * from(
select ROW_NUMBER() over(partition by groupdate order by groupdate)as rn,* from #trades)x
where rn <=3
In DolphinDB, one can use context-by clause to solve similar problems. For your question, use the code below:
select * from trades context by symbol, date limit -3
A negative value -3 for limit clause tells the system to get last 3 records for each symbol and date combination.

how to get latest date column records when result should be filtered with unique column name in sql?

I have table as below:
I want write a sql query to get output as below:
the query should select all the records from the table but, when multiple records have same Id column value then it should take only one record having latest Date.
E.g., Here Rudolf id 1211 is present three times in input---in output only one Rudolf record having date 06-12-2010 is selected. same thing with James.
I tried to write a query but it was not succssful. So, please help me to form a query string in sql.
Thanks in advance
You can partition your data over Date Desc and get the first row of each partition
SELECT A.Id, A.Name, A.Place, A.Date FROM (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Date DESC) AS rn
FROM [Table]
) A WHERE A.rn = 1
you can use WITH TIES
select top 1 PERCENT WITH TIES * from t
order by (row_number() over(partition by id order by date desc))
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=280b7412b5c0c04c208f2914b44c7ce3
As i can see from your example, duplicate rows differ only in Date. If it's a case, then simple GROUP BY with MAX aggregate function will do the job for you.
SELECT Id, Name, Place, MAX(Date)
FROM [TABLE_NAME]
GROUP BY Id, Name, Place
Here is working example: http://sqlfiddle.com/#!18/7025e/2

MAX() for 2 Dates Separately

I am trying to find a way to get the Max Date from one field and then to remove duplication get the Max of those dates from another field.
So far I have managed to get the Max of the Effective Dates, but need to get the Max timestamp from those values to remove duplication.
Here is what I have so far:
SELECT
a2.CUST_ID
, Address
, Effective_Date --DATE variable
, Timestamp_Entry --DATETIME variable
FROM
(SELECT
CUST_ID
, MAX (Effective_Date) as Most_Effective_Date
FROM Address_Table
GROUP BY CUST_ID) a1
JOIN Address_Table a2
ON a1.CUST_ID = a2.CUST_ID and a1.Most_Effective_Date = a2.Effective_Date
(Some timestamp entrys may be newer entries with older effective date, which is why the Effective Date takes priority, and then the TimeStamp should remove duplicates
I think this is what you want:
select a.*
from (select a.*,
row_number() over (partition by cust_id order by effective_date desc, timestamp_entry desc) as seqnum
from address_table a
) a
where seqnum = 1;
This returns the "most recent" address for each customer based on the two columns.

For each unique value of some groupid column, how do I get rows with last 3 dates?

I have a table with columns: FILING_ID, DATE, and BLAH
I'm trying to write a query that for each FILING_ID, returns the rows with the last three dates. If table is:
FILING_ID DATE
aksjdfj 2/1/2006
b 2/1/2006
b 3/1/2006
b 4/1/2006
b 5/1/2006
I would like:
FILING_ID DATE
aksjdfj 2/1/2006
b 3/1/2006
b 4/1/2006
b 5/1/2006
I was thinking of maybe running some query to figure out the 3rd highest date for each FILING_ID then doing a join and comparing the cutoff date with the DATE?
I use PostgreSQL. Is there some way to use limit?
SELECT filing_id, date -- more columns?
FROM (
SELECT *, row_number() OVER (PARTITION BY filing_id ORDER BY date DESC NULLS LAST) AS rn
FROM tbl
) sub
WHERE rn < 4
ORDER BY filing_id, date; -- optionally order rows
NULLS LAST is only relevant if date can actually be NULL.
If date is not unique, you may need to break ties to get stable results.
PostgreSQL sort by datetime asc, null first?
Select first row in each GROUP BY group?
Is there some way to use limit?
Maybe. If you have an additional table holding all distinct filing_id (and possibly a few more, which are removed by the join), you can use CROSS JOIN LATERAL (, LATERAL is short syntax):
SELECT f.filing_id, t.*
FROM filing f -- table with distinct filing_id
, LATERAL (
SELECT date -- more columns?
FROM tbl
WHERE filing_id = f.filing_id
ORDER BY date DESC NULLS LAST
LIMIT 3 -- now you can use LIMIT
) t
ORDER BY f.filing_id, t.date;
What is the difference between LATERAL and a subquery in PostgreSQL?
If you don't have a filing table, you can create one. Or derive it on the fly:
Optimize GROUP BY query to retrieve latest record per user