MYSQL: Weekly , Monthly and Yearly Report - mysql

i want to make report that can be viewed by weekly , monthly and yearly.
for example:
i want to see who enrolled by weekly , or i want to see who enrolled in this month or year and also about the payments. i want to see the enrollee this june . i want to see the enrollee this 2010 by using a dropdown search.
// this is my code for my weekly report which i want to see students who enrolled last week but i dnt know if my code is correct.
$datetoday=date("Y-m-d");
$result = mysql_query("
SELECT enrollee_info.*, payments.* from enrollee_info
INNER JOIN payments on payments.enrollee_id=enrollee_info.e_id
WHERE enrollee_info.category='Walk In'
AND DATE_FORMAT(payments.entrydate , %Y-%m-d')>=SUBDATE('".$datetoday."' , INTERVAL 7 DAY)");
with monthly and yearly , for example i want to see who enrolled this month etc. and i want to see who enrolled this year by using a dropdown that you can select month or the year you want to search.

Take a look at the manual regarding the acceptable units for INTERVAL. You can simply use a switch to determine the range for your records.
In your drop down you'll have week, month or year. You can then use a switch to prepare your statement.
$sql = "SELECT enrollee_info.*,
payments.*
FROM enrollee_info
INNER JOIN payments
ON payments.enrollee_id = enrollee_info.e_id
WHERE enrollee_info.category = 'Walk In'
AND payments.entrydate >= Subdate(Curdate(), ";
switch ($range) {
case "month":
$sql .= 'INTERVAL 1 MONTH';
break;
case "year":
$sql .= 'INTERVAL 1 YEAR';
break;
//if no match, use week
default:
$sql .= 'INTERVAL 1 WEEK';
}
$sql .= ')';
Which would create a statement like this:
SELECT enrollee_info.*,
payments.*
FROM enrollee_info
INNER JOIN payments
ON payments.enrollee_id = enrollee_info.e_id
WHERE enrollee_info.category = 'Walk In'
AND payments.entrydate >= Subdate(Curdate(), INTERVAL 1 week)
If possible, try to avoid fetching all columns from each table and use a column list.

Related

How To Count Total Present Attendance From Database

I have a table where I need to count all present to show how many attendance student have
In my table have Following Column
school id
Student id
year
Month
Status
day_1
day_2
day_3
To
day_31
entry goes once in a month. Like
if new month new row create
else update in day_ 1 day_2 day_3 etc.
Here's a different trick. Although it's for MySql 8.0+
Concatinate the day_n fields into a string.
Then remove all the characters that aren't 'P' from that string.
Then the character length of the remaining string will be the total 'P'.
SELECT school_id, student_id, month, year,
CHAR_LENGTH(
REGEXP_REPLACE(
CONCAT_WS('' -- using concat_ws because concat returns null when one of the fields is null
, day_1
, day_2
-- add more day_n here
, day_31),'[^P]+','')) AS present
FROM YourTable
A more conventional approach might look something like this:
student_id,
attendance_date
You can made a query to get the IDs of all students,
$sql2 = "SELECT distinct id from table";
$query = $this->db->query($sql2);
foreach ($query->result() as $innerrow) {
HERE YOU USE THE SYNTAX OF NEXT CODE-BLOCK
}
Inside the foreach loop you can use the id with $row->id to generate another sql query
with an where clause.
$sql = "SELECT table.* from table where id = ".$row->id;
$query = $this->db->query($sql);
foreach ($query->result() as $row) {
print your data
}
write query to find the attendance with present like
select (if(day_1 in('P'),1,0)+if(day_2 in('P'),1,0)+if(day_3 in('P'),1,0)+if(day_4 in('P'),1,0)+if(day_5 in('P'),1,0)+if(day_6 in('P'),1,0) + if(day_7 in('P'),1,0)+if(day_8 in('P'),1,0)+if(day_9 in('P'),1,0)+....+if(day_n in('P'),1,0)) as day_present from tbl_name
But the if condition for all 31 days or 30 days as per months days
just try it once in your mysql query editor You will get the exact result..
In codeigniter
$result = $this->db->select("(if(day_1 in('P'),1,0)+if(day_2 in('P'),1,0)+if(day_3 in('P'),1,0)+if(day_4 in('P'),1,0)+........+if(day_n in('P'),1,0)) as present, school_id, student_id,year, month, status");
$this->db->get('table_name');

Sql query mistake for the weekly statistics

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!

How to sort products in Magento by best selling from the last month, mysql query based style?

I managed to overwrite the Mage/Catalog/Model/Config.php and make a method that adds a new sorting option called "Sort By Top Sellers".
I also added a where statement where I can get data from last month but the collection doesn't output all the products, only the ones buyed in the last month (I need to sort all the products, not only the ones from last month).
The query outputs correct without the where statement.
Any idea on how to solve this ?
public function sortByTopSelling($dir){
$today = time();
$last = $today - (60*60*24*30);
$from = date("Y-m-d H:i:s", $last);
$to = date("Y-m-d H:i:s", $today);
$this->getSelect()->joinLeft('sales_flat_order_item AS order_item','e.entity_id = order_item.product_id',
'SUM(order_item.qty_ordered) AS ordered_qty')->where('`order_item`.`created_at` > "'.$from.'"')->group('e.entity_id')->order('ordered_qty DESC');
}
Debated a while between replying as a comment or an answer because I am not 100% sure on the Magento Code.
MYSQL:
select e.entity_id, SUM(order_item.qty_ordered) AS ordered_qty
from magento.catalog_product_entity as e
left join magento.sales_flat_order_item AS order_item on e.entity_id = order_item.product_id and order_item.created_at > DATE_FORMAT(NOW() ,'%Y-%m-01')
group by e.entity_id
order by ordered_qty DESC;
I don't have a reliable way to test the Magento code, but it should be something along the lines of:
$this->getSelect()->joinLeft('sales_flat_order_item AS order_item',"e.entity_id = order_item.product_id and order_item.created_at > $from",
'SUM(order_item.qty_ordered) AS ordered_qty')->group('e.entity_id')->order('ordered_qty DESC');
The other way to do it would be to add or order_item.created_at is null to the where, but this will take longer to run than another join condition, and in my Magento DB, the query already takes a staggering 90 seconds, but my tables are massive, it may work for your implementation.

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