Sql query mistake for the weekly statistics - mysql

I am trying to make a weekly statistics for user registration. It should work for weekly. There are total of seven days in a week. I want to print the number of users who are registered every day in the week on the screen.
For example:
Number of users who registered on Monday = 38
Number of users who registered on Tuesday = 11
.... .... and this list will only list the week we were
I created a sql query like the following:
SELECT WEEKDAY(registerTime)+1, count(*)
FROM users group by WEEKDAY(registerTime)
ORDER BY WEEKDAY(registerTime)
But the outcome of this question is very different. This total shows the number of users who registered on Monday for every year .

You want to limit users to only this week so you don't get everything:
SELECT WEEKDAY(registerTime)+1, count(*)
FROM users
WHERE WEEKOFYEAR(registerTime) = WEEKOFYEAR(CURDATE())
AND YEAR(registerTime) = YEAR(CURDATE())
group by WEEKDAY(registerTime)
ORDER BY WEEKDAY(registerTime);
Basically you match the year and week of year with what you need. That should be enough.

Try like this :
SELECT datepart(week, registerTime), count(*) FROM Users GROUP BY datepart(week, registerTime)

You can also use Php code for this purpose. First make array of days and then you can get registered users for each day through that array
function today()
{
return date("Y-m-d");
}
function last_seventh_day()
{
return date("Y-m-d",strtotime("-7 days"));
}
$days = ['Saturday','Sunday','Monday','Tuesday','Wednesday','Thursday','Friday'];//Array that stores all days
foreach($days as $day)
{
$sql = "select * FROM users where day = '$day' and date_column between " .today() . "and" .last_seventh_day() ;
}
I have updated my answer. I hope this will work for you!

Related

Laravel: write query to count sales with group by weeks

I have mysql database having a sales table, representing a list of products sold daily, with columns of product name, price and created_at. I could get the number of sales for a certain day by doing this for instance;
$sales = Sale::where('created_at', $certain_day')->count();
However, i need to track the sales per week for a number of weeks, say the number of products sold from the beginning of this week (sunday) till date, the number of sales last week, the number of sales two weeks ago and so on, for the last five weeks, returned as an array (something like this:[{30/12/2021: 10}, {25/12/2021: 15}, {18/12/2021: 22}]. How can i write laravel eloquent query to achieve this?
Try something like this:
$from = date('2018-01-01');
$to = date('2018-05-02');
Sale::whereBetween('created_at', [$from, $to])->get();
Then you can use Carbon method for current week, previous week, next week
Sale::whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()])->get();
#update
Sale::selectRaw('*,UNIX_TIMESTAMP(created_at) DIV '.$sec. ' as group_date')->groupBy('group_date');
For week,month and day you can do
->groupBy(function($data) {
// day
return Carbon::parse($data->created_at)->format('Y-m-d');
//month
return Carbon::parse($data->created_at)->format('Y-m');
//week
return Carbon::parse($data->created_at)->format('W');
})
This following query gives you the last 5 weeks with the count of sales in each week:
SELECT FROM_DAYS(TO_DAYS(created_at) - MOD(TO_DAYS(created_at), -1, 7)) AS weeklyGrouping , COUNT(*) AS sales_count
FROM sales
GROUP BY weeklyGrouping
ORDER BY weeklyGrouping DESC
LIMIT 5
The formula above assumes that Sunday is the first day of the week and in case your weeks start on Mondays, change the -1 to -2.
for descriptive information you can refer to this article.
EDIT (Eloquent query builder Style)
$sales = Sale::selectRaw('COUNT(*) AS sales_count')
->selectRaw('FROM_DAYS(TO_DAYS(created_at) - MOD(TO_DAYS(created_at), -1, 7)) AS weeklyGrouping')
->groupBy('weeklyGrouping')
->orderBy('weeklyGrouping', 'DESC')
->take(5);

create a ranking and statistics with repeated database records

Today I want to get a help in creating scores per user in my database. I have this query:
SELECT
r1.id,
r1.nickname,
r1.fecha,
r1.bestia1,
r1.bestia2,
r1.bestia3,
r1.bestia4
r1.bestia5
FROM
reporte AS r1
INNER JOIN
( SELECT
nickname, MAX(fecha) AS max_date
FROM
reporte
GROUP BY
nickname ) AS latests_reports
ON latests_reports.nickname = r1.nickname
AND latests_reports.max_date = r1.fecha
ORDER BY
r1.fecha DESC
that's from a friend from this site who helped me in get "the last record per user in each day", based on this I am looking how to count the results in a ranking daily, weekly or monthly, in order to use statistics charts or google datastudio, I've tried the next:
select id, nickname, sum(bestia1), sum(bestia2), etc...
But its not giving the complete result which I want. That's why I am looking for help. Additionally I know datastudio filters where I can show many charts but still I can count completely.
for example, one player in the last 30 days reported 265 monsters killed, but when I use in datastudio my query it counts only the latest value (it can be 12). so I want to count correctly in order to use with charts
SQL records filtered with my query:
One general approach for get the total monsters killed by each user on the latest X days and make a score calculation like the one you propose on the commentaries can be like this:
SET #daysOnHistory = X; -- Where X should be an integer positive number (like 10).
SELECT
nickname,
SUM(bestia1) AS total_bestia1_killed,
SUM(bestia2) AS total_bestia2_killed,
SUM(bestia3) AS total_bestia3_killed,
SUM(bestia4) AS total_bestia4_killed,
SUM(bestia5) AS total_bestia5_killed,
SUM(bestia1 + bestia2 + bestia3 + bestia4 + bestia5) AS total_monsters_killed,
SUM(bestia1 + 2 * bestia2 + 3 * bestia3 + 4 * bestia4 + 5 * bestia5) AS total_score
FROM
reporte
WHERE
fecha >= DATE_ADD(DATE(NOW()), INTERVAL -#daysOnHistory DAY)
GROUP BY
nickname
ORDER BY
total_score DESC
Now, if you want the same calculation but only taking into account the days of the current week (assuming a week starts on Monday), you need to replace the previous WHERE clause by next one:
WHERE
fecha >= DATE_ADD(DATE(NOW()), INTERVAL -WEEKDAY(NOW()) DAY)
Even more, if you want all the same, but only taking into account the days of the current month, you need to replace the WHERE clause by:
WHERE
MONTH(fecha) = MONTH(NOW())
For evaluate the statistics on the days of the current year, you need to replace the WHERE clause by:
WHERE
YEAR(fecha) = YEAR(NOW())
And finally, for evaluation on a specific range of days you can use, for example:
WHERE
DATE(fecha) BETWEEN CAST("2018-10-15" AS DATE) AND CAST('2018-11-10' AS DATE)
I hope this guide will help you and clarify your outlook.
This will give you number of monster killed in the last 30 days per user :
SELECT
nickname,
sum(bestia1) as bestia1,
sum(bestia2) as bestia2,
sum(bestia3) as bestia3,
sum(bestia4) as bestia4,
sum(bestia5) as bestia5
FROM
reporte
WHERE fecha >= DATE_ADD(curdate(), interval -30 day)
GROUP BY nickName
ORDER BY

Select all users whose birthday is in this week (Monday - Sunday)

I am trying to display all users whose birthday is within this week (Monday to Sunday). After searching everywhere I was able to get this but it's displaying users from last week and this week also.
SELECT * FROM teachers WHERE WEEK(birthday, 0) = WEEK(NOW(), 0)
Change the second argument for the WEEK function. I think that you want it to be either 3 or 5. Based on the documentation.
Setting the mode to 0 would get people whose birthdays are on Sunday in the previous week based on what you are saying in your question.
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_week
Check MySQL's function WEEKOFYEAR. You could use it like this to get users with birthday in current week:
SELECT * FROM teachers WHERE WEEKOFYEAR(birthday) = WEEKOFYEAR(NOW())
Use function WEEKOFYEAR:
SELECT * FROM teachers WHERE WEEKOFYEAR(birthday) = WEEKOFYEAR(NOW());
WEEKOFYEAR returns a number in the range 1 to 53.

How to get data from mysql and group them in weeks, also separating by month

I have mysql database and is full of over 2 years of data. How can I make a query in a way that it will get the result as below?:
January
Week 1
...
data rows here
....
Week 2
...
...
Week 3
...
...
Week 4
...
...
February (same as above)
These are the field structures:
- date (in yyyy-mm-dd format)
- job (integer autoincrement)
- person (varchar)
Try this, it will generate output pretty similar to one required by you
SELECT MONTH(date) AS MONTH, WEEK(date) AS WEEK, DATE_FORMAT(date, %Y-%m-%d) AS DATE, job AS JOB, person AS PERSON GROUP BY WEEK(date);
GROUP BY year(record_date), MONTH(record_date)
Check out the date and time functions in MySQL.
It has to be a query, or you can use ajax too? Using ajax you could do a loop in javascript:
date = [initial date]
while date <= [final date] {
divUpdate = 'divrecs'; // will be used in updateDiv function
url = 'getrecs.php?date1='+date+'&date2='+(date+6);
conecta(url,updateDiv);
date = date+7;
}
And inside getrecs your query would be:
$stmt = $dbh->prepare("select * from yourtable where date >= '".$_GET['date1']."' and date <= '".$_GET['date2']."'");
if ($stmt->execute()) {
while ($row = $stmt->fetch(PDO::FETCH_BOTH)) {
echo "Do anything with your data here: $row[1] etc<BR>";
}
}
Hope that helps!
SELECT
MONTH(created_datetime) AS month,
WEEK(created_datetime) AS week,
DATE(created_datetime) AS date,
COUNT(id) AS count
FROM users
WHERE date(created_datetime) BETWEEN '2017-05-01' AND '2017-12-31'
GROUP BY month
ORDER BY created_datetime
If you want records date wise that you need to use GROUP BY date.
If you want records weekly that you need to use GROUP BY week.
If you want records monthly that you need to use GROUP BY month.

mySQL Query to list number of comments my site received each day?

I run an online magazine and would like a dead-simple way to track 3 metrics:
How many comments are left each day.
How many links my users submit.
How many new members I get each day.
This information is all my database, I'm just not sure how to get it out.
I have a "comments" table with about 3500 comments. Each comment gets a row in the table. One of the columns in the table is "timestamp."
I'm assuming there's a query that will select this table, sort the rows by timestamp, group them in 24-hour increments and then count the number of rows in each group - telling me how many new comments I received each day.
What would that query look like? I think I can figure out the other ones if I had the first one working.
This fragment will display your results in a themed table:
$sq = 'SELECT COUNT(*) cnt, DATE(FROM_UNIXTIME(timestamp)) day '
. 'FROM {comments} c '
. 'GROUP BY 2 '
. 'ORDER BY 2 DESC';
$q = db_query($sq);
$stats = array();
while ($o = db_fetch_object($q)) {
$stats[$o->day] = array($o->day, $o->cnt);
}
return theme('table', NULL, $stats));
Using DATE(timestamp) doesn't work because comments.timestamp is in UNIX_TIMESTAMP format, whereas DATE() expects an ASCII date.
Use the date_format() function to format the dates;
select count(id) as commentCount, date_format(dateColumn, '%Y-%m-%d') as commentDate
from yourTable
group by commentDate