I want to get the count of the registered users in the past 7 days, grouped.
+-----+------------+--------------+
| id | username | created |
+-----+------------+--------------+
| 1 | Vlad | 1360168194 |
+-----+------------+--------------+
| 2 | Test | 1360168194 |
+-----+------------+--------------+
This is my table. I want to have 7 rows of results with the date of the day, and count(id) as the result for the users that registered.
I tried different solutions and none of them really fitted my needings. Are there any ideas?
SELECT DATE(FROM_UNIXTIME(columName)), COUNT(ID) totalCOunt
FROM tableName
WHERE DATE(FROM_UNIXTIME(columName)) BETWEEN CURDATE() + INTERVAL -7 DAY AND CURDATE()
GROUP BY DATE(FROM_UNIXTIME(columName))
SQLFiddle Demo
Other Source(s)
MySQL Date and Time Functions
Related
Storage table
| id| product_id | date_add | date_remove
------------------------------------------------------------------
| 1 | 10 |2018-04-02 08:28:43 | 2018-04-03 07:21:08
| 2 | 10 |2018-04-05 08:28:43 | 2018-04-06 08:28:50
| 3 | 10 |2018-04-01 08:28:43 | 2018-04-05 08:28:50
| 4 | 12 |2018-04-01 08:28:43 | 2018-04-03 07:21:08
| 5 | 12 |2018-04-04 08:28:43 | 2018-04-04 10:28:43
| 6 | 13 |2018-03-01 08:28:43 | 2018-03-01 10:28:43
how to find ?
how many days product was in the storage in period 2018-04-01 to 2018-04-05?
find result
| product_id | days
| 10 | 5
| 12 | 3
try
SELECT product_id, SUM(DATEDIFF(date_remove, date_add)) as days
FROM storage
where date_remove BETWEEN '2018-04-01 00:00:00'
AND '2018-04-05 23:59:59'
AND date_add BETWEEN '2018-04-01 00:00:00'
AND '2018-04-05 23:59:59'
GROUP BY product_id
but result wrong because 'SUM' sums all days
get result
| product_id | days
| 10 | 7
correct result
| product_id | days
| 10 | 5
upd
http://rextester.com/QFS96125
result 9,646805555556 but probably maximum 5 days and product_id 13 correct 0,436608796296 but result 0,87
First you want to look at all date ranges that are within or overlap with the range 2018-04-01 to 2018-04-05.
where date_add < date '2018-04-06' and date_remove >= date '2018-04-01'
Then, with the ranges found, you want to consider only their days in the range 2018-04-01 to 2018-04-05.
greatest(date_add, date '2018-04-01')
least(date_remove, date '2018-04-06')
Then you want to count days. Here you need a rule. Do you want to look at single ranges and only take their full days which you add up then? Or do you want to consider day fractions, add all up and see how many full days result? For the latter you could get durations in seconds and add these up:
select
product_id,
sum(timestampdiff(second, greatest(date_add, date '2018-04-01'),
least(date_remove, date '2018-04-06'))
) / 60 / 60 / 24 as days
from storage
where date_add < date '2018-04-06' and date_remove >= date '2018-04-01'
group by product_id
order by product_id;
This gets you
product_id | days
-----------+---------------
10 | 5,599872685185
12 | 2,036400462963
Feel free to use FLOOR, CEIL or ROUND on the resulting days.
Rextester demo: http://rextester.com/XTVU47656
To obtain such result, try
SELECT SUM(DATEDIFF(date_remove, date_add)) as days
FROM table
GROUP BY product_id
Keep in mind that this will sum all the days for the same product_id. To get the result for each id, use:
SELECT id, product_id, DATEDIFF(date_remove, date_add) as days
FROM table
I know it's possible to get yesterday records, most common way using SUBDATE(CURDATE(), 1) or maybe simply use CURDATE() - 1 and use LIMIT and ORDER to retrieve the last record of yesterday.
But here, I need to get the last record of yesterday in the first row and the rest will be all records of today. I need to run this within single query.
For example, I have following records in one of my table:
--------------------------------------------------
| value | created_at |
--------------------------------------------------
| 70 | 1/1/2017 |
| 300 | 1/1/2017 |
| 100 | 1/1/2017 |
| 235 | 1/2/2017 |
| 45 | 1/2/2017 |
--------------------------------------------------
The created_at column is a timestamp, if today is 1/2/2017 (2th January 2017) then the result of the query should be:
--------------------------------------------------
| value | created_at |
--------------------------------------------------
| 100 | 1/1/2017 |
| 235 | 1/2/2017 |
| 45 | 1/2/2017 |
--------------------------------------------------
So far, I only able to retrieve the records of today with following query:
SELECT * FROM my_table WHERE created_at >= CURDATE();
What query I need to accomplish this?
Hoping you have id as primary key
select * from
(select
*
from
tbl
where date(created_at) =date(DATE_ADD(now(), INTERVAL -1 DAY))
order by id desc limit 0,1
)tmp
UNION
select * from tbl where date(created_at)=date(now())
I'm creating a booking system and one of the requirements is for a mass 'Regular' booking to be added automatically.
I believe an easy solution to this would be to store all members 'regular' days in a table, then have a scheduled event that retrieves all the records and inserts each row as a record in the bookings table.
Regulars Table
|id | memberid | time | day | group |
____________________________________________
| 1 | 42 | 08:00 | Monday| 2 |
| 2 | 42 | 08:00 | Friday| 1 |
| 3 | 25 | 11:00 | Friday| 1 |
____________________________________________
As the days are stored as VARCHAR textual, i need a way to generate the next day as y/m/d. In PHP this would be date('Y-m-d', strtotime('next tuesday'));
So i'd like to know what the correct way to achieve the following:
for each row returned
insert into bookings (memberid,time,date,group) values (row[memberid], row[time], the next row[day], row[group]
This query gives you the next week day:
select id,
memberid,
t.time,
date_add(curdate(),
interval 6 +
FIND_IN_SET(t.day,'Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday')
- weekday(curdate()) day) as nextWeekDay
,t.group
from T
SqlFiddle demo
I try to do a simple query to select from a database and only select rows which fit to the statement of being older than 12 months.
The table is like (mydate actually is a datetime field):
+----+---------+-------------+
| id | account | mydate |
+----+---------+-------------+
| 1 | 1 | last week | <-- this should disqualify account 1
| 2 | 1 | 2 years ago |
| 3 | 1 | 3 years ago |
| 4 | 2 | 2 years ago |
+----+---------+-------------+
And this is my query by now:
SELECT id, account, MAX(mydate)
FROM awesomeTable
WHERE
mydate < SUBDATE(CURDATE(), INTERVAL 12 MONTH)
GROUP BY account
Seems nice. But the results are like following:
+----+---------+-------------+
| id | account | mydate |
+----+---------+-------------+
| 2 | 1 | 2 years ago | <-- SQL doesnt understand me :(
| 4 | 2 | 2 years ago |
+----+---------+-------------+
But I don't want to let account 2 show up at all. I really just want to see accounts where mydate is older than 2 years.
With that query now it doesnt show ID 1 as this doesnt fit the condition in the WHERE clause. But it will show me the newest possible mydate of the other rows.
I want to get a list of all accounts which mydates are ALL older than 1 year. How can i achieve that?
There WHERE condition is done to select the rows first, then MAX() is applied to those results. Use HAVING to operate on the results after aggregating.
SELECT id, account, MAX(mydate) AS maxdate
FROM awesometable
GROUP BY account
HAVING maxdate < DATE_SUB(NOW(), INTERVAL 12 MONTH)
Note that this will not necessarily show the id of the line with the maximum date. For that, you need a join:
SELECT a.id, a.account, a.mydate
FROM awesometable AS a
JOIN (
SELECT account, MAX(mydate) AS maxdate
FROM awesometable
GROUP BY account
HAVING maxdate < DATE_SUB(NOW(), INTERVAL 12 MONTH)) AS b
ON a.account = b.account AND a.mydate = b.maxdate
have this portion of a large table T;
+---------------+------------+
| session_id | visit_time |
+---------------+------------+
| 4f89cebc109f9 | 1334431476 |
| 4f89cf283d21c | 1334431528 |
| 4f89cf283d21c | 1334431534 |
| 4f89cf3b350a6 | 1334431547 |
| 4f89cf42ab640 | 1334431554 |
+---------------+------------+
I want to find number of session_id weekday-wise. Session_id is not primary key. So I tried:
select count(distinct(session_id)) from T group by weekday(from_unixtime(time))
But it won't work because if same session_id has visit_time on two different sundays, then it counts them as 1, although it rightly counts 1 when same session_id has visit_time on same sunday.
The expected thing is : I want to know how many session-ids have visit day as sun, mon etc. If a session_id has visited on two different sundays, then they are counted twice, but if on same sunday, then only 1 count.
So how can I do it in Mysql ?
use WEEK instead of WEEKDAY
SELECT WEEK(FROM_UNIXTIME(time)) WeekNo,
DATE_FORMAT(FROM_UNIXTIME(time),'%a') WeekName,
COUNT(DISTINCT(session_id))
FROM T
GROUP BY WEEK(FROM_UNIXTIME(time)),
DATE_FORMAT(FROM_UNIXTIME(time),'%a')
WEEK