ranking based on multiple tables - mysql

select a.no, a.Dtime,count(b.Dtime)+1 as Rank
from table1 a left
join table1 b on a.Dtime>b.Dtime and a.no=b.no
group by a.no,a.Dtime
order by a.no, a.Dtime
table1 Input:
NO Dtime
1 08:10:00
1 09:10:00
1 09:40:00
1 10:10:00
2 09:30:00
2 10:15:00
3 09:00:00
Output:
NO Dtime Rank
1 08:10:00 1
1 09:10:00 2
1 09:40:00 3
1 10:10:00 4
2 09:30:00 1
2 10:15:00 2
3 09:00:00 1
But I am looking for Output in mysql where table2 Rank links to table1 and table2 Dtime i.e. table1.Dtime>table2.time
table2 Input
NO Dtime
1 08:30:00
1 09:15:00
1 09:50:00
2 08:30:00
2 09:45:00
3 09:50:00
Output:
NO table1.Dtime Rank table2.Dtime
1 08:10:00 0 00:00:00
1 09:10:00 1 08:30:00
1 09:40:00 2 09:15:00
1 10:10:00 3 09:50:00
2 09:30:00 1 08:30:00
2 10:15:00 2 09:45:00
3 09:00:00 0 00:00:00

You can use the same approach with your initial query. Just left join to table2. To get the Dtime from table2 you can use a correlated subquery:
select a.no, a.Dtime,
count(b.Dtime) as Rank,
coalesce((select c.Dtime
from table2 as c
where c.no = a.no and a.Dtime > c.Dtime
order by c.Dtime desc limit 1), '00:00:00') as t2Dtime
from table1 a
left join table2 b on a.Dtime > b.Dtime and a.no = b.no
group by a.no,a.Dtime
order by a.no, a.Dtime
Demo here

Related

Find rows where ID matches and date is within X days

Somewhat new to SQL and I'm running into a bit of issue with a project. I have a table like this:
ID
subscription_ID
renewal_date
1
11
2022-01-01 00:00:00
2
11
2022-01-02 00:00:00
3
12
2022-01-01 00:00:00
4
12
2022-01-01 12:00:00
5
13
2022-01-01 12:00:00
6
13
2022-01-03 12:00:00
My goal is to return rows where the subscription_ID matches and the start_date is within or equal to a certain # of days (hours would work as well). For instance, I'd like rows where subscription_ID matches and the start_date is within or equal to 1 day such that my results from the table above would be:
ID
subscription_ID
renewal_date
1
11
2022-01-01 00:00:00
2
11
2022-01-02 00:00:00
3
12
2022-01-01 00:00:00
4
12
2022-01-01 12:00:00
Any assistance would be greatly appreciated--thanks!
If I understand correctly maybe you are trying something like:
select t.*
from test_tbl t
join ( SELECT subscription_id
, MAX(diff) max_diff
FROM
( SELECT x.subscription_id
, DATEDIFF(MIN(y.start_date),x.start_date) diff
FROM test_tbl x
JOIN test_tbl y ON y.subscription_id = x.subscription_id
AND y.start_date > x.start_date
GROUP BY x.subscription_id , x.start_date
) z
GROUP BY subscription_id
) as t1 on t.subscription_id=t1.subscription_id
where t1.max_diff<=1;
Result:
id subscription_id start_date
1 11 2022-01-01 00:00:00
2 11 2022-01-02 00:00:00
3 12 2022-01-01 00:00:00
4 12 2022-01-01 12:00:00
The subquery returns:
subscription_id max_diff
11 1
12 0
13 2
which is used on the where condition.
Demo

How do I make count return 0 with group by 5 min if no records appear in that group?

Here is my code:
select case when count(distinct player) > 0 then count(distinct player) else 0 end as 'num',
FROM_UNIXTIME(UNIX_TIMESTAMP(Timestamp2) DIV 300) as '5m',
GameID from table_4
where Timestamp2 between '2018-05-01' and '2018-05-02'
group by UNIX_TIMESTAMP(Timestamp2) DIV 300, GameID
My data structure looks like:
player date GameID
1 2018-05-10 00:00:00 1
2 2018-05-10 00:01:00 2
3 2018-05-10 00:02:00 3
4 2018-05-10 00:03:00 4
2 2018-05-10 00:06:00 5
And I tried to get:
num 5m GameID
1 2018-05-10 00:00:00 1
1 2018-05-10 00:00:00 2
1 2018-05-10 00:00:00 3
1 2018-05-10 00:00:00 4
0 2018-05-10 00:00:00 5
0 2018-05-10 00:05:00 1
0 2018-05-10 00:05:00 2
0 2018-05-10 00:05:00 3
0 2018-05-10 00:05:00 4
1 2018-05-10 00:05:00 5
My code doesn't show up row 5 when GameID 5 is not played in the first 5 minute.
I'm new to mySQL, and I have tried for several days and still didn't solve it
Thanks for everybody
Use a cross join to generate the rows and then left join to bring in the values:
select m.fivemin, g.gameid,
count(distinct t.player)
from (select distinct FROM_UNIXTIME(UNIX_TIMESTAMP(Timestamp2) DIV 300)
as fivemin
from table_4
) m cross join
(select distinct gameid
from table_4
) g left join
table_4 t4
on t4.gameid = g.gameid and
group by g.gameid, m.fivemin;

Select Max and Min datetime for distinct user

I have a record as below
ID(int) DATA_ORA(timestamp) BADGE LETTORE
1 2017-04-01 09:30:00 1 1
2 2017-04-01 12:30:00 1 2
3 2017-04-01 13:30:00 1 1
4 2017-04-01 18:30:00 1 2
5 2017-04-01 09:30:00 2 1
6 2017-04-01 18:30:00 2 2
7 2017-04-02 09:30:00 1 1
8 2017-04-02 18:30:00 1 2
9 2017-04-03 09:30:00 3 1
10 2017-04-03 12:30:00 3 2
11 2017-04-03 13:30:00 3 1
12 2017-04-03 18:30:00 3 2
I want to get the first access time and the last daily logout time (for each day) for each individual user (badge).
How I can do this?
The record I wish to as below
ID(int) DATA_ORA(timestamp) BADGE LETTORE
1 2017-04-01 09:30:00 1 1
4 2017-04-01 18:30:00 1 2
5 2017-04-01 09:30:00 2 1
6 2017-04-01 18:30:00 2 2
7 2017-04-02 09:30:00 1 1
8 2017-04-02 18:30:00 1 2
9 2017-04-03 09:30:00 3 1
12 2017-04-03 18:30:00 3 2
Is it possible to do that? Thanks.
NOTE: ID are auto-incremented and LETTORE 1 is entry and LETTORE 2 is exit.
You can do it grouping by date, badge and lettore like:
SELECT date(DATA_ORA),badge,lettore, case when lettore=1 then min(time(data_ora))
when lettore=2 then max(time(data_ora))
else 0
end
FROM table1
group by date(DATA_ORA),badge,lettore
try below using correlated subquery and union all
select * from tablename a
where DATA_ORA in (select min(DATA_ORA) from tablename b where a.badge=b.badge)
union
select * from tablename a
where DATA_ORA in (select max(DATA_ORA) from tablename b where a.badge=b.badge)
I like #fa06 answer, but he misses, that you want the data daily.
so try this:
select * from t1 a
where DATA_ORA in (select min(DATA_ORA) from t1 b where a.badge=b.badge GROUP BY DATE_FORMAT(DATA_ORA, '%Y%m%d'))
union
select * from t1 a
where DATA_ORA in (select max(DATA_ORA) from t1 b where a.badge=b.badge GROUP BY DATE_FORMAT(DATA_ORA, '%Y%m%d'));
Here is the executed version of your table and query that gives output in the order you needed, on DB-fiddle.
Try this query:
select * from EntryExitLogs where id in
(select id from EntryExitLogs where (badge,data_ora)= any
(select badge,min(data_ora)from EntryExitLogs group by date(data_ora),badge))
union
(select * from EntryExitLogs where id in
(select id from EntryExitLogs where (badge,data_ora)= any
(select badge,max(data_ora)from EntryExitLogs group by date(data_ora),badge)))
order by id;
I think its better to make use of the ID column for selecting the rows, because the timestamp column contains duplicates.
You could use a join with subquery for badge 1 and badge 2
select t1.badge, min_dat, nax_date
from (
select badge, min_(data_ora) min_data
from my_table
where lettore = 1
group by badge
) t1
INNER JOIN (
select badge, max_(data_ora) max_data
from my_table
where lettore = 2
group by badge
) t2 ON t1.badge = t2.badge

How to filter a sql request with DISTINCT and multiple results [duplicate]

This question already has answers here:
How can I SELECT rows with MAX(Column value), PARTITION by another column in MYSQL?
(22 answers)
Closed 4 years ago.
I want to filter the results, by not showing the same SAISON_ID, but to choose the SAISON_ID that have the most recent DATE_START
SELECT saison_id, date_start, date_end FROM saison
This request give me this result :
saison_id date_start date_end
0 2018-01-05 2018-01-12
0 2019-01-19 2019-02-05
1 2018-01-15 2018-02-13
2 2018-02-17 2018-03-24
3 2018-03-25 2018-06-12
4 2018-06-13 2018-09-18
5 2018-07-05 2018-11-19
6 2018-08-28 2018-11-20
7 2018-11-21 2019-01-17
If I do that :
SELECT DISTINCT(saison_id), date_start, date_end FROM saison GROUP BY saison_id
I have this new result :
saison_id date_start date_end
0 2018-01-05 2018-01-12
1 2018-01-15 2018-02-13
2 2018-02-17 2018-03-24
3 2018-03-25 2018-06-12
4 2018-06-13 2018-09-18
5 2018-07-05 2018-11-19
6 2018-08-28 2018-11-20
7 2018-11-21 2019-01-17
How can I get this instead ? (look the saisonID 0)
saison_id date_start date_end
0 2019-01-19 2019-02-05
1 2018-01-15 2018-02-13
2 2018-02-17 2018-03-24
3 2018-03-25 2018-06-12
4 2018-06-13 2018-09-18
5 2018-07-05 2018-11-19
6 2018-08-28 2018-11-20
7 2018-11-21 2019-01-17
Hi use this query to get the desired result
select id,[start],[end]
from
(select Row_Number() over(Partition By id order by [start] Desc) as Rownum,* from #session) a
where Rownum =1
In case this query is little complex to you then you can use this one also with the same result
select a.id,a.[start],a.[end] from #session a
inner join (select id, max([start]) as mx_s from #session group by id) b
on a.id = b.id and a.[start] = b.mx_s

selecting duplicate values with a condition from a mysql table

I have the following table in mysql:
Key DI CI FD FA NM Valid_from Valid_to
0 1224468 123 2012-06-30 3 6 2013-01-23 9999-12-31
1 1234567 123 2013-12-31 3 10 2014-02-27 2014-03-10
2 1234567 123 2013-12-31 2 12 2014-03-10 9999-12-31
3 1234579 123 2013-12-31 3 12 2014-05-15 9999-12-31
4 1234595 123 2013-12-31 1 12 2014-06-30 9999-12-31
5 122469 123 2015-11-11 1 6 2015-11-11 9999-12-31
6 1224470 123 2015-11-11 2 12 2015-11-11 9999-12-31
7 1224471 123 2015-11-11 3 15 2015-11-11 9999-12-31
8 1224472 123 2015-11-10 2 13 2015-11-10 9999-12-31
9 1224473 123 2015-11-10 3 12 2015-11-10 9999-12-31
If there are records which has the same "FD", I need to get the ones which 's "FA" is "1", if exists.
Basically, I want this output.
Key DI CI FD FA NM Valid_from Valid_to
0 1224468 123 2012-06-30 3 6 2013-01-23 9999-12-31
4 1234595 123 2013-12-31 1 12 2014-06-30 9999-12-31
5 122469 123 2015-11-11 1 6 2015-11-11 9999-12-31
8 1224472 123 2015-11-10 2 13 2015-11-10 9999-12-31
9 1224473 123 2015-11-10 3 12 2015-11-10 9999-12-31
It looks a complicated query, and I couldn't manage to do it.
How can I do it?
Thanks
Looks like a job for
...
GROUP BY FD
...
HAVING COUNT(FD) > 1
I don't see why you'd want 2012-06-30 in your results? I thought you only wanted ones where there is an FA of 1?
Try out following query:
select * from tbl group by fd having count(*)=1
union all
select t1.* from tbl t1 inner join (
select max(`key`) as `key` from tbl where fa=1 group by fd
) t2 on t1.`key`=t2.`key` group by FD;
SELECT T1.*
FROM table_name T1 LEFT JOIN
(SELECT * FROM table_name GROUP BY `FD` HAVING COUNT(*)>1 ) T2 ON T1.`FD`=T2.`FD` AND T1.`FA` <>1
WHERE T2.`FD` IS NULL
Can you check this.
Hope this helps.