mysql select top 10 of IDs by time period - mysql

Here is the table:
Id
time
QQa
2020-11-04 10:00:10
QQa
2020-11-05 20:17:04
QQa
2020-10-08 13:27:01
WWs
2020-10-09 14:08:44
WWs
2020-10-09 13:07:46
WWs
2020-10-09 13:26:57
RRe
2020-10-08 13:06:39
I'm trying to sort/get top 10 of such table by time diff. Here is the output I need (in days):
ID
Days
QQa
4
WWS
1
RRe
1
and so on...
So QQa took ~4 days others have timestamps within one day.
I'm trying to do it by something like this:
SELECT id, Min(time)
AS In Time, Max(time)
AS Out Time,
DATEDIFF(Max(time), Min(time))
AS Time Diff
FROM database.table GROUP BY id, DATE(time)
ORDER BY Time Diff ASC;
I'm afraid I'm not successful in what I'm doing. Any help is appreciated.
upd. https://stackoverflow.com/users/816613/nick-maroulis answer is the query I need. Thank you!
select ID, datediff( max(time), min(time) ) Days
from table
group by id
order by Days desc
limit 10

Related

How to find whether the same customers who ordered this month also ordered the next month?

I have an orders table
Order_id User_id Order_date
1 32 2020-07-19
2 24 2020-07-21
3 27 2020-07-27
4 24 2020-08-14
5 32 2020-08-18
6 32 2020-08-19
7 58 2020-08-20
Now I want to find how many of the users ordered in 1st month also ordered in the next month. In this case, user_id's 32,24,27 ordered in 7th month but only 24 and 32 ordered in the next month.
I want the result to be like :
Date Retained_Users Total_users
2020-07 Null 3
2020-08 2 3
I'm lost here. Can someone please help me with this?
In MySQL 8.0, you can do this with window functions:
select
order_month,
count(distinct case when cnt_orders_last_month > 0 then user_id end) retained_users,
count(distinct user_id) total_users
from (
select
user_id,
date_format(order_date, '%Y-%m-01') as order_month,
count(*) over(
partition by user_id
order by date(date_format(order_date, '%Y-%m-01'))
range between interval 1 month preceding and interval 1 day preceding
) cnt_orders_last_month
from mytable
) t
group by order_month
The logic lies in the range specification of the window function; it orders record by month, and counts how many orders the customer placed last month. Then all that is left to do is aggregate and count distinct users.
Demo on DB Fiddle

mysql group by day and count then filter only the highest value for each day

I'm stuck on this query. I need to do a group by date, card_id and only show the highest hits. I have this data:
date card_name card_id hits
29/02/2016 Paul Stanley 1345 12
29/02/2016 Phil Anselmo 1347 16
25/02/2016 Dave Mustaine 1349 10
25/02/2016 Ozzy 1351 17
23/02/2016 Jhonny Cash 1353 13
23/02/2016 Elvis 1355 15
20/02/2016 James Hethfield 1357 9
20/02/2016 Max Cavalera 1359 12
My query at the moment
SELECT DATE(card.create_date) `day`, `name`,card_model_id, count(1) hits
FROM card
Join card_model ON card.card_model_id = card_model.id
WHERE DATE(card.create_date) >= DATE(DATE_SUB(NOW(), INTERVAL 1 MONTH)) AND card_model.preview = 0
GROUP BY `day`, card_model_id
;
I want to group by date, card_id and filter the higher hits result showing only one row per date. As if I run a max(hits) with group by but I won't work
Like:
date card_name card_id hits
29/02/2016 Phil Anselmo 1347 16
25/02/2016 Ozzy 1351 17
23/02/2016 Elvis 1355 15
20/02/2016 Max Cavalera 1359 12
Any light on that will be appreciated. Thanks for reading.
Here is one way to do this. Based on your sample data (not the query):
select s.*
from sample s
where s.hits = (select max(s2.hits)
from sample s2
where date(s2.date) = date(s.date)
);
Your attempted query seems to have no relationship to the sample data, so it is unclear how to incorporate those tables (the attempted query has different columns and two tables).

MySQL Selecting MAX total with date and ID

I have a cron script that writes the total number of active users to a table every day. I'm trying to now generate a simple report that would show the "high water mark" for each month. Because some accounts expire during the month it's possible the highest number may NOT be at the end of the month.
Here's a sample of my table structure
tblUserLog
-----------
record_id INT(11) // PRIMARY KEY
run_date DATE // DATE RUN
ttl_count INT(11) // TOTAL FOR DAY
Sample data:
record_id run_date ttl_count
1 2013-06-01 500
2 2013-06-10 510
3 2013-06-20 520
4 2013-06-30 515
5 2013-07-01 525
6 2013-07-10 530
7 2013-07-20 540
8 2013-07-31 550
9 2013-08-01 560
What I would like returned is:
record_id run_date ttl_count
3 2013-06-20 520
8 2013-07-31 550
9 2013-08-01 560
I've tried two queries that are close...
// This will give me the total for the first of the month
SELECT s.record_id, s.run_date, s.ttl_count
FROM tblStatsIndividual s
JOIN (
SELECT record_id
FROM tblStatsIndividual
GROUP BY DATE_FORMAT(run_date, '%Y %m')
HAVING MAX(ttl_count)
) s2
ON s2.record_id = s.record_id
ORDER BY run_date DESC
This returns the total for the first of each month, along with the record_id and correct date for the total.
Tried this...
SELECT record_id,max(run_date), max(ttl)
FROM (
SELECT record_id,run_date, max(ttl_count) AS ttl
FROM tblStatsIndividual
GROUP BY DATE_FORMAT(run_date, '%Y %m')
) a
GROUP BY DATE_FORMAT(run_date, '%Y %m')
ORDER BY run_date DESC
This one appears to get the correct "high water mark" but it's not returning the record_id, or the run_date for the row that IS the high water mark.
How do you get the record_id and the run_date for the highest total?
Something like
Select detail.Record_ID, detail.Run_Date, detail.ttl_Count
From tblStatsIndividual detail
Inner Join
(Select Year(run_date) as Year, Month(Run_date) as Month, Max(ttl_count) as ttl
From tblStatsIndividual
Group By Year(run_date), Month(Run_date)) maximums
On maximums.Year = Year(detail.Run_date) and maximums.Month = Month(detail.Run_date)
and maximums.ttl = detail.ttl_count
Should do it. NB based on your requirement if you had two records in the same month with the same (and highest in the month) ttl_count, they would both be returned.
Based on the help from #Tony Hopkinson, This query gets me the info. The one caveat is it shows the ID and date for the first occurrence of the MAX total, so if the total is the same three days in a row on a month, the first day's ID is returned. For my purpose, the last ID would be more ideal, but I can live with this:
SELECT s.Record_ID, s.Run_Date, s.ttl_Count
FROM tblStatsIndividual s
INNER JOIN (
SELECT YEAR(run_date) AS yr, MONTH(run_date) AS mon, MAX(ttl_count) AS ttl
FROM tblStatsIndividual
GROUP BY DATE_FORMAT(run_date, '%Y %m')
) maximums
ON maximums.yr = YEAR(s.run_date)
AND maximums.mon = MONTH(s.run_date)
AND maximums.ttl = s.ttl_Count
GROUP BY ttl_count
ORDER BY run_date DESC

Rush Hour table for every day in a month MySQL

I'm trying to make a query to get rush hours for everyday on a specific month.
The table I have looks like this:
id idproduct created_at
1 021354684 2011-10-01 20:25:48
2 033546835 2011-10-01 20:30:15
3 055965654 2011-10-01 20:45:20
4 012975343 2011-10-02 14:03:36
5 021354684 2011-10-02 15:55:48
6 033546835 2011-10-02 16:30:15
7 055965654 2011-10-02 16:45:20
8 012975343 2011-10-02 18:53:36
9 021354684 2011-10-03 08:55:48
10 033546835 2011-10-03 09:30:15
11 055965654 2011-10-03 14:03:20
12 012975343 2011-10-03 14:03:36
What I try to get is something like this...:
day rush_hour number_of_rows
1 20:00 3
2 16:00 5
3 14:00 4
Is it possible to get a table like this? can you guys help me?
I made a mistake, sorry for this. The number of rows should be the total of items sold that day, not in that hour :( sorry.
http://sqlfiddle.com/#!2/5b87b/7
First, count every day's every hour's count (into a view, because we will use it twice below):
CREATE VIEW hours AS
SELECT
DATE( created_at ) AS d,
HOUR( created_at ) AS h,
COUNT(*) AS c
FROM item
GROUP BY DATE(created_at), HOUR(created_at);
Final query:
SELECT
hours.d AS `day`,
hours.h AS `rush_hour`,
hours.c AS `count`
-- get the max count for every day
FROM (
SELECT
d, -- the day
MAX(c) as c -- the count
FROM hours
GROUP BY d
) AS maxc
-- find the actual hour(s) with the max count for every day:
INNER JOIN hours ON hours.c = maxc.c
AND hours.d = maxc.d;
You're going to want to look at the MySQL Date Functions, they offer you some help with this
SELECT
day(created_at) as day,
hour(created_at) as rush_hour,
count(1) as num_rows
FROM item
GROUP BY
day(created_at), hour(created_at)
http://sqlfiddle.com/#!2/62a15/2/0
Try this:
SELECT dayofyear(created_at) as day, hour(created_at) as rush_hour, count(*) as number_of_rows
FROM table
GROUP BY dayofyear(created_at), hour(created_at);
Here it is without making a view:
SELECT ddd.day, eee.rush_hour, ddd.maxo
FROM
(select day, max(num_rows) as maxo from (
SELECT
day(created_at) as day,
hour(created_at) as rush_hour,
count(1) as num_rows
FROM item
GROUP BY
day(created_at), hour(created_at)
) as groupo group by day) as ddd
LEFT JOIN
(SELECT
day(created_at) as day,
hour(created_at) as rush_hour,
count(1) as num_rows
FROM item
GROUP BY
day(created_at), hour(created_at)
) as eee on ddd.day=eee.day and ddd.maxo=eee.num_rows
I could imagine it being formatted more nicely or having more relevant aliases, but there's just so much subselecting going on here.
And thanks SQLfiddlers for putting the data there.
And I think that if you have two hours tied for the highest number of whatever it is you are counting, they both will show up, so you'll get two (or more) records returned for that day of the month.

MySQL distinct and left, right

I have a table with day column like this:
2011-04-28, 2011-04-29 ...
day count name surname
2011-04-28 8 titi tutu
2011-04-28 12 tutu toto
2011-04-27 2 tutu toto
2011-03-12 10 tutu toto
I can obtain distinct day but not only month and year.
select distinct(day) from Table where day between "2011-03-01" and "2011-04-28";
I want only distinct month and year.
Can you help me?
Thanks
select DISTINCT EXTRACT(YEAR_MONTH FROM `day`) as yearmonth
from Table
where day between '2011-03-01' and '2011-04-28';
DISTINCT may be applied only to the whole row in mysql. So, you need to extract what you need first from the date.
select distinct(EXTRACT YEAR_MONTH FROM `day`) from Table
where day between "2011-03-01" and "2011-04-28";