Limiting sequential values โโof one column in sql query
You can add a where clause that filters out rows for which there are 4 lower rows photo_id
:
select *
from YourTable t1
where 4 > (
select count(*)
from YourTable t2
where t1.event_id = t2.event_id
and t1.photo_id < t2.photo_id
)
limit 100
This can get slow for huge tables. A faster, but very MySQL-specific option is to use variables. For instance:
select *
from (
select
@nr := case
when event_id = @event then @nr + 1
else 1
end as photonr
, @event := event_id
, t1.*
from YourTable as t1
cross join (select @event := -1, @nr := 1) as initvars
order by event_id
) as subquery
where subquery.photonr < 5
limit 100;
Test data used:
drop table if exists YourTable;
create table YourTable (
id int auto_increment primary key
, event_id int
, photo_id int
);
insert into YourTable (event_id, photo_id)
values (1,1), (1,2), (1,3), (1,4), (1,5), (2,1), (1,6);
a source to share
If you are using T-SQL take a look at http://msdn.microsoft.com/en-us/library/ms189798.aspx for ranking functions.
From your question, it looks like NTILE is what you want. Here's my quick attempt at requesting, I'm not in a terminal so it doesn't validate, but you need to start:
SELECT
id,
event_id,
photo_id,
created_at,
NTILE(4) OVER (ORDER BY photo_id) AS 'Quartile'
FROM tbl
WHERE NTILE(4) OVER (ORDER BY photo_id)<2
ORDER BY created_at DESC
The linked page has a good example of all the ranking features.
Good luck.
a source to share
Try the following:
SELECT p.id, p.event_id, p.photo_id, p.created_at
FROM photo_table p,
(
SELECT photo_id, MAX(created_at) max_date
FROM photo_table
GROUP BY photo_id
) t
WHERE p.created_at = t.max_date
AND p.photo_id = t.photo_id
ORDER BY p.created_at DESC
LIMIT 100
What it does: 1. find the last date the photo was changed 2. find only the latest events of each photo 3. select the first 100 most recent
In PostgreSQL or Oracle, this would be easier with analytics / windows functions like:
FIRST (created_at) OVER (PARTITION BY photo_id ORDER BY created_at DESC)
a source to share