Reputation: 3538
My database looks something like this
Value | Date | parent_id
y | 2019-01-01 | 1
n | 2019-01-02 | 1
n | 2019-01-03 | 1
I want to write a query that will look for a row that has parent_id = 1
and value = 'y'
, and also evaluate it against other rows that have parent_id=1'
but will check to make sure the date
is greater than its row's date.
So in this case it won't return anything.
If the data was like:
Value | Date | parent_id
y | 2019-01-04 | 1
n | 2019-01-02 | 1
n | 2019-01-03 | 1
Then it would return the first row.
If it means anything, I am using SQLite.
Upvotes: 1
Views: 42
Reputation: 222432
With SQLite >= 3.25, simply use window function ROW_NUMBER()
:
SELECT * FROM (
SELECT t.*, ROW_NUMBER() OVER(PARTITION BY t.parent_id ORDER BY t.date DESC) rn
FROM mytable t
) x WHERE rn = 1 AND parent_id = 1 AND value = 'y'
Window function are usually more efficient than correlated subqueries.
The query works as follows.
First, it traverses the table and uses ROW_NUMBER()
to assign a a rank to each record within the group of records having the same parent_id
, and with the record with the highest date
numbered 1
. You can run the subquery to see what it actually returns (it gets more interesting when there is more than one parent_id
) :
SELECT t.*, ROW_NUMBER() OVER(PARTITION BY t.parent_id ORDER BY t.date DESC) rn
FROM mytable t
Then, all that is left to do to is filter on the target parent_id
, pick the record with row number 1 (ie the record that has the highest date
for this parent_id
), and make sure that it has value = 'y'
.
Upvotes: 1
Reputation: 1269563
Another method just looks for the last row to see if it meets your conditions:
select t.*
from (select t.*
from t
where t.parent_id = 1
order by t.date desc
limit 1
) t
where value = 'y';
This checks that the last row with parent_id = 1
has the value of 'y'
.
Upvotes: 0
Reputation: 164069
You can use NOT EXISTS:
select * from tablename t
where
parent_id = 1 and value = 'y'
and not exists (
select 1 from tablename
where parent_id = t.parent_id
and date > t.date
)
See the demo.
As a suggestion: since you are using SQLite,you should consider to change the format of the Date
column to YYYY-MM-DD
, so that it is comparable.
Upvotes: 1