MySQL cyclically one row for each valid user - mysql

Here's the background, I have a table object containing :
id
user (id from user table)
date (date)
state (0|1)
And another table user containing :
id
state (0|1)
EX.:
Object
ID | USER | DATE | STATE
1 1 2012-10-01 1
2 2 2012-08-01 1
3 3 2012-10-01 1
4 3 2012-10-02 1
5 3 2012-09-01 1
6 3 2012-10-01 1
7 1 2012-10-02 1
8 2 2012-10-02 0
9 2 2012-10-02 1
10 1 2012-10-01 1
11 2 2012-10-01 1
12 3 2012-10-01 0
13 4 2012-11-11 1
Users
ID | STATE
1 | 1
2 | 1
3 | 1
4 | 0
I would make a request to display one object per valid state user cyclically, if object state is active, order by date DESC.
EX. result :
ID | USER | DATE | STATE
10 1 2012-11-01 1
9 2 2012-10-02 1
4 3 2012-10-02 1
7 1 2012-10-02 1
11 2 2012-10-01 1
3 3 2012-10-01 1
1 1 2012-10-01 1
2 2 2012-08-01 1
6 3 2012-10-01 1
5 3 2012-09-01 1
I can do simple queries but then I admit to not knowing how to do here.
EDIT 2012-11-22 :
Let trying another approch... With this query (thanks Michiel van Vaardegem), I have a list of users, in order that I want... the one with freshness object on top.
SELECT o.user
FROM object o
INNER JOIN users ON user.id = o.user
WHERE o.state=1 AND users.state=1
GROUP BY o.user
ORDER BY o.date DESC
Result is :
USER
1
2
3
NEW QUESTION APPROCH :
With this list of ids, the possible calculated count of rows, and user defined vars, do you think something could be done?
Exemple :
Assuming this list, SELECT * FROM object WHERE user IN
($thislist) AND state=1 ORDER BY date DESC
For each object row depending of user (here I don't know how to explain in mysql)
incrementing a rank var with the userposition(in cycle) + usercount
ORDER BY rank LIMIT n,x that result
I whant to rank my objects in a user cycle, like :
object from user 1,2,3,1,2,3,1,3,3,1,1,1,1,1,1,1,1,etc... if exist
Do this new approch algo be realizable in a mysql query, and if possible how... that is the great question?
Can anybody see a solution only in MySQL?
Thanks in advance

Something like:
SELECT o.id, o.user, o.date, 1 AS state
FROM object o
INNER JOIN user ON u.id = o.user
WHERE o.state = 1 AND u.state = 1
GROUP BY o.user, o.date
ORDER BY o.user, o.date DESC
I'm not sure, but if I read it correctly, you only want records where the state in both tables is '1', correct?
And you want to sort first on user and then on the date desc?

Related

MySQL group rows

I have a table with:
Id (id of rider)
Time (is the time that he has done)
Session (number session where the time was done)
idlap idRider session time
1 45652 1 4
2 54645 1 2
3 45652 2 2
4 54582 2 1
5 51284 1 3
6 54582 1 3
7 54645 2 4
8 51284 2 5
9 54582 2 2
I wonder how to query in MySQL a result like:
idRider |fast sesion | count laps
45652 | 2 | 1
54645 | 1 | 1
51284 | 3 | 1
54582 | 2 | 2
The query should return in which session the rider got the best time(fast session) and count the number of laps (done in the fast session) grouped by idRider.
Thank you.
This query will give you the results that you want. It JOINs the laps table to the minimum time and number of laps per rider per session, and then to the minimum time per rider to get the fastest session:
SELECT l.idRider, l.session, l.time, s.numlaps
FROM laps l
JOIN (SELECT idRider, `session`, MIN(time) AS fastest, COUNT(*) AS numlaps
FROM laps
GROUP BY idRider, `session`) s ON s.idRider = l.idRider AND s.session = l.session AND s.fastest = l.time
JOIN (SELECT idRider, MIN(time) AS fastest
FROM laps
GROUP BY idRider) f ON f.idRider = s.idRider AND f.fastest = s.fastest
ORDER BY idRider
Output:
idRider session time numlaps
45652 2 2 1
51284 1 3 1
54582 2 1 2
54645 1 2 1
Demo on dbfiddle

How to join to single row in one to many relationship in SQL?

I want to join one to many table with single row on many table by limit 1 and order by create date
tbl_cart :
id fullname
1 myname1
2 myname2
3 myname3
tbl_cart_status:
id cart_id status created_at
1 1 33 2018-09-20
2 1 34 2018-09-23
3 2 34 2018-09-21
4 1 100 2018-09-25
5 2 35 2018-09-29
How can i get output with sql like this:
I want to get lastest status of my cart by ordered with created_at column
myname cart_id status created_at
myname1 1 100 2018-09-25
myname2 2 35 2018-09-29
Think filtering for this type of query:
select c.name, cs.*
from tbl_cart c join
tbl_cart_status cs
on c.id = cs.cart_id
where cs.created_at = (select max(cs2.created_at)
from tbl_cart_status cs2
where cs2.cart_id = cs.cart_id
);

How to check for one value in multiple rows

Whats the best way to check if different groups of rows in a table with the same GroupID such as different teams have a SINGLE captain? Captain Identifier for example could be '10', so its crucial that it goes through multiple records with the same groupID and checks to see if theres ONLY ONE record with the positionID as '10'. I need it to do it for all teams, i.e all groupID's
-------------------------------------------------
ID | Group ID | Name | Position|
-------------------------------------------------
1 1 John 3
2 1 jim 3
3 1 Hahn 4
4 1 Mary 4
5 1 Moe 4
6 1 Charlie 10
7 2 taylor 4
8 2 Geoff 4
9 2 adam 4
10 2 cam 10
11 3 sharon 2
12 3 tony 4
13 3 steve 3
14 3 eve 4
15 3 gwen 10
--------------------------------
So what I need it to do is check that every groupID only had ONE 10 as the position.
Thanks in advance guys. Check out the image link at the bottom.
im using mysql btw
Sorry if this is badly described
If I understood you - I think you need something like :
select groupId, sum(case when positionID='10' then 1 else 0 end) as captains
from tbl_name
group by groupID
having captains = 1
am I close???
If I understood you correctly, you want an indication that will tell you whether the groupID had more then one captain.
So what you need is this:
select groupID,case when cnt = 1 then 1 else 0 end as IND_ONE_CAPTAIN from (
select groupID, sum(case when positionid = '10' then 1 else 0 end) as cnt
from players
group by groupID)
Now IND_ONE_CAPTAIN columns consist 1 or 0, 1 is for the group id only had 1 captain, and 0 is when they had more.

Most recent distinct record from a joined MySQL table

I have two tables, one of a list of competition results, and one with ELO ratings (based on previous competitions).
Fetching the list of competitors for an arbitrary competition is trivial enough, but I also need to get the most recent rating value for them.
score:
id | eventid | competitorid | position
1 1 1 1
2 1 2 2
3 1 3 3
4 2 2 1
5 2 3 2
6 3 1 1
7 3 3 2
8 3 2 3
rating:
id | competitorid | rating
1 1 1600
2 2 1500
3 3 1500
4 2 1600
5 3 1590
Expected output for a query against score.eventid = 3 would be
id | competitorid | position | rating
6 1 1 1600
7 3 2 1590
8 2 3 1600
At the moment my code looks like:
SELECT score.scoreID, score.competitorID, score.position,
rating.id, rating.rating
FROM score, rating
WHERE score.competitorid = rating.competitorid
AND score.eventid = 3
ORDER BY score.position
which gives an output of
id | competitorid | position | rating.id | rating
6 1 1 1 1600
7 3 2 2 1500
7 3 2 4 1590
8 2 3 3 1500
8 2 3 5 1600
basically it's showing the data from the score table for that correct event, but giving me a row for every rating available against that competitorID unfortunately I have no idea where to build in the DISTINCT statement or how to limit it to the most recent result.
MySQL noob, and managed DISTINCT statements, but not with joins. Unfortunately most previous questions seemed to deal with getting distinct results from a single table, which is not quite what I'm after. Thanks!
One way to get the rating is with a correlated subquery:
SELECT s.scoreID, s.eventID, s.competitorID, s.position,
(select r.rating
from rating r
where s.competitorID = r.competitorID
order by r.id desc
limit 1
) as rating
FROM score s
WHERE s.eventID = 3
ORDER BY s.position;
I'm not sure what ratingprid is, so this only includes the rating.

Select min/max from multiple items

I'll try to explain it as simple as possible:
First some database structure with dummy data.
Structure
tb_spec_fk
feature value
-----------------
1 1
1 2
1 3
1 4
1 5
2 2
2 3
3 1
3 4
4 2
4 3
4 4
5 1
5 3
5 5
6 3
6 5
tb_spec_feature
feature_id filter
------------------
1 2
2 2
3 2
4 2
5 1
6 0
tb_spec_value
value_id name
----------------
1 10
2 20
3 30
4 40
5 50
Now, what I want is the follow result
Result
feature_id min_value max_value
---------------------------------
1 10 50
2 20 30
3 10 40
4 20 40
But how?
Logic
Get from the tb_spec_feature where "filter" equals 2 the highest and lowest values which are present in the tb_spec_value table and connected together trough the tb_spec_fk table.
My attemps
A lot! But I'll spare you :)
SELECT
f.feature_id AS feature_id,
MAX(value.name) AS max_value,
MIN(value.name) AS min_value
FROM tb_spec_feature AS f
JOIN tb_spec_fk AS fk ON f.feature_id=fk.feature
JOIN tb_spec_value AS value ON fk.value=value.id
WHERE f.filter=2
GROUP BY f.feature_id
The two JOIN statements "link" the a feature to a value. GROUP BY groups all rows with the same feature id, and then you can take the min or max or any other aggregate function on those columns.
Demo
Here is how you can do it
select
tsf.feature_id,
tsvl.name as Min_Value,
tsvr.name as Max_Value
from tb_spec_feature as tsf
inner join (select feature , MIN(value) MinV,MAX(value)MaxV from tb_spec_fk group by feature order by feature)as tsfkl on tsfkl.feature = tsf.feature_id
left join tb_spec_value as tsvl on tsvl.value_id = tsfkl.MinV
left join tb_spec_value as tsvr on tsvr.value_id = tsfkl.MaxV
where tsf.filter = 2
group by tsf.feature_id
Output
feature_id | Min_Value | Max_Value
---------------------------------
1 | 10 | 50
2 | 20 | 30
3 | 10 | 40
4 | 20 | 40
Fiddle Demo