Number of Posts as per days in a month - mysql

There is a table Post in my database which contains posts of different users. What I wanna do is to create an sql query that'll return as per respective month the number of posts being made each day. Kindly let me know how can i do that generically in one query i can create multiple queries for all days but that is a worst case scenario. So I need expert's solution to this.
Thanks
Expected output:
(Query counts the number of posts for all the days in a respective month)
Day : Number of posts
1 : 20
2 : 25
3 : 10
4 : 17
.........................
30 : 6
Table Structure:
ID | postid | post | date

select DAYOFMONTH(date) as Day , count(*) as Number_of_posts
from table
group by DAYOFMONTH(date)
You should know that if table contains data from different months number of posts will be wrong.
So the group by should be by date and you should use date in selected instead of day of month.

SELECT DAYOFMONTH(date), count(*) FROM Post
GROUP BY DAYOFMONTH(date)
ORDER BY DAYOFMONTH(date) ASC;
If you want to query for a specific month (say, February) then use this:
SELECT DAYOFMONTH(date), count(*) FROM Post
WHERE MONTH(date) = '2'
GROUP BY DAYOFMONTH(date)
ORDER BY DAYOFMONTH(date) ASC;
Note: Months are returned in number form where the MONTH() function is used.
EDIT: If you're looking to return counts for EVERY day in a given month, then I'd push you here - a great accepted answer to a similar question: How to get values for every day in a month

SELECT date, COUNT(id) as number_of_posts FROM table_name GROUP BY date.

Related

MySQL: Aggregate weekly statistics with substatics (subqueries)

I would like to gather weekly statics on a MySQL-Table.
The table itself has the following structure:
user_id action_id created
0 123 2017-01-01 00.00:00
0 124 ...
1 123 ...
... ... ...
I would like to aggregate the weekly statics for:
How many user where active per week
This is rather simple:
SELECT
YEARWEEK(created) as week,
COUNT(DISTINCT user_id) AS count
FROM data
GROUP BY YEARWEEK(created);
Additionally I could apply a sorting.
The result looks like:
week count
201701 2
201702 3
How many user where active per week for the very first time
I thought about solving it by using a subquery
SELECT
YEARWEEK(created) as week,
COUNT(DISTINCT user_id) AS count,
(
SELECT
COUNT(DISTINCT d2.user_id)
FROM data d2
WHERE YEARWEEK(d2.created) = week
AND NOT EXISTS (SELECT 1 FROM data d3
WHERE YEARWEEK(d3.created) < week AND d2.user_id = d3.user_id)
) as countNewUsers
FROM data d1
GROUP BY YEARWEEK(created);
How many junior user where active per week
Junior users were active between 1 and 10 times before the related week
Similar to the one above, but with other subquery
How many power user where active per week
Senior users were active more than 10 times before the related week
This works as expected, but has a rather poor performance, since the subquery is evaluated before the grouping happens. With millions of rows in a table, this takes ages.
Does anybody have a better solution for this query, ideally returning all values in single result set?
I think all of your queries could derive from one 'intermediate' table. It would contain (yearweek, userid, count).
Users active per week: Pretty much the same query, but faster from this table.
Active for first time: Self-join ON userid and desired week versus MIN(yearweek)
Uses before the target week: ... SUM(count) WHERE ... < week GROUP BY userid
Use the above to determine which userids of Junior/Power.

How to sum order total amount by week

I am trying to retrieve last 3 months records. I need to sum order total amount by week. I have made following query.
select CONCAT("Week", WEEK(created_at)) as week_number, sum(total_cost)
from certified_diamond_orders
where created_at > 2016-11-22
and status = "delivered"
group by week("created_at")
But I am only getting one record with this. Infact my table has 2 years entries. Also I was trying to figure out how I can pull week start date and end date to diplay on my chart.
Any suggestions where I am making mistake?
week("created_at") looks like you're trying to determine the week of the string "created_at" rather than the column created_at. Which might explain why you're only getting one row in your result.
The date 2016-11-22 also looks suspiciously like a sum instead of a date (2016 - 11 - 22 = 1983 vs "2016-11-22"
Try this:
SELECT
CONCAT('Week', WEEK(created_at)) AS week_number,
SUM(total_cost)
FROM certified_diamond_orders
WHERE
created_at > '2016-11-22' AND
status = 'delivered'
GROUP BY WEEK(created_at)

select total of field for the last 7 days and group by date and values

I am sure this is pretty simple but I cannot figure out what I am doing incorrectly here. I am trying to get totals for certain fields over the last 7 days and group them by date and field.
Example:
The following table:
TABLE API_LOG
COLUMNS
customer
ip_address
date_logged
endpoint
So I would like to get the total endpoint calls for the last 7 days per customer and ip_address. I already have the daily totals organized but for some reason cannot get this to group correctly.
SELECT date_logged AS DATE_LOG, Customer,
COUNT(customer) AS CustomerCount, COUNT(ip_address) as IPCOUNT
FROM API_log
GROUP BY date_logged, Customer
The idea is then to bind this to a chart.
Sample data:
Expected output;
Current Output:
Appreciate assistance with this.
edit:
I group by date because I want to see the total for each day for the last 7 days. In other words, give me the total counts for each customer by day.
I think your date_logged column is datetime so it makes sense that you are getting separate dates when grouping. Try this
SELECT CAST(date_logged AS DATE) AS DATE_LOG, Customer,
COUNT(customer) AS CustomerCount, COUNT(ip_address) as IPCOUNT
FROM API_log
GROUP BY CAST(date_logged AS DATE), Customer

How to get the average price for the X most recent rows based on date?

I am looking to calculate moving averages over variable dates.
My database is structured:
id int
date date
price decimal
For example, I'd like to find out if the average price going back 19 days ever gets greater than the average price going back 40 days within the past 5 days. Each of those time periods is variable.
What I am getting stuck on is selecting a specific number of rows for subquery.
Select * from table
order by date
LIMIT 0 , 19
Knowing that there will only be 1 input per day, can I use the above as a subquery? After that the problem seems trivial....
if you only have one input per day you don't need id, date can be your primary id? Am i missing something? Then use select sum
SELECT SUM(price) AS totalPrice FROM table Order by date desc Limit (most recent date),(furthest back date)
totalPrice/(total days)
I may not understand your question
Yes you can use that as a sub-query like this:
SELECT
AVG(price)
FROM
(SELECT * FROM t ORDER BY date DESC LIMIT 10) AS t1;
This calculates the average price for the latest 10 rows.
see fiddle.

Group results by period

I have some data which I want to retrieve, but I want to have it grouped by a specific number of seconds. For example if my table looks like this:
| id | user | pass | created |
The created column is INT and holds a timestamp (number of seconds from 1970).
I would want the number of users that are created between last month and the current date, but show them grouped by let's say 7*24*3600 (a week). So if in the range there are 1000 new users, have them show up how many registered each week (100 the first week, 450 the second, 50 the third and 400 the 4th week -- something like this).
I've tried grouping the results by created / 7*24*3600, but that's not working.
How should my query look like?
You need to use integer division div otherwise the result will turn into a real and none of the weeks will resolve to the same value.
SELECT
(created div (7*24*60*60)) as weeknumber
, count(*) as NewUserCount
FROM users
WHERE weeknumber > 1
GROUP BY weeknumber
See: http://dev.mysql.com/doc/refman/5.0/en/arithmetic-functions.html
You've got to keep the integer part only of that division. You can do it with the floor() function.
Have you tried select floor(created/604800) as week_no, count(*) from users group by floor(created/604800) ?
I assume you've got the "select users created in the last month" part sorted out.
Okay here are the possible options you may try:
GROUP BY DAY
select count(*), DATE_FORMAT(created_at,"%Y-%m-%d") as created_day FROM widgets GROUP BY created_day
GROUP BY MONTH
select count(*), DATE_FORMAT(created_at,"%Y-%m") as created_month FROM widgets GROUP BY created_month
GROUP BY YEAR
select count(*), DATE_FORMAT(created_at,"%Y") as created_year FROM widgets GROUP BY created_year