php sum column based on year criteria - php

I'm trying to sum a column named "total_fee" where the payment date is equaled to the current year but I received a blank. The code works with no error but the query came up empty. The payment_date is a datetime/timestamp. Does anyone know the php statement to sum current year and last year total? I have tried various ways with no lucks.
$stmt2 = $DB_CON_C->prepare("SELECT SUM(total_fee) AS current_year
FROM `".$row['email']."`
WHERE payment_date = date('Y')");
$stmt2->execute();
$sum2 = $stmt2->fetch(PDO::FETCH_ASSOC);
echo '<td>' .$sum2['current_year'].'</td>'

You need to supply the date value, not a php expression for the date.
You are also using prepared statements incorrectly. Look here https://www.w3schools.com/php/php_mysql_prepared_statements.asp
An easy way to test your query is to use 'between'
... WHERE payment_date BETWEEN '2017-01-01' AND '2017-12-31'

Related

MySql Query for Current Date

I have s MySQL Query where I want to pull data from my database but base it on the current month information
FROM lbs_trace_etrack WHERE (lbs_agent = '$slfirstname' AND DATE (lbs_date) = CURDATE()) ORDER BY lbs_date DESC LIMIT 0,50");
This string pulls out the information for the current day.
I have also tried the below string but get no results from it:
FROM lbs_trace_etrack WHERE (lbs_agent = '$slfirstname' AND MONTH(lbs_date) = (MONTH(NOW()) AND YEAR(lbs_date) = YEAR(NOW())
My table date format is as follow 2016-08-02
Or using PHP variables as so:
<?php
$start = date('Y-m-01'); // FIRST DAY OF CURRENT MONTH
$end = date("Y-m-t", strtotime(date("Y-m-d"))); // LAST DAY OF CURRENT MONTH
$sql = "SELECT * FROM lbs_trace_etrack WHERE lbs_agent = '".$slfirstname."' AND (lbs_date BETWEEN '".$start."' AND '".$end."')";
?>
I have done the following and it works
FROM lbs_trace_etrack WHERE lbs_agent = '$slfirstname' AND MONTH(lbs_date) = MONTH(CURDATE()) AND YEAR(lbs_date) = YEAR(CURDATE()) ORDER BY lbs_date ASC, lbs_time ASC
Thanks to all and Tijo for guidance
Assuming lbs_agent is a DATE field type as mentioned in comments, you could do this (note I am just showing the pertinent date part of your WHERE clause):
WHERE lbs_agent >= DATE_FORMAT(NOW() ,'%Y-%m-01')
It is important that you do not use a function call on the left (field definition) side of the WHERE comparison, as you will then not be able to leverage any index on that field. Doing this would require a full table scan with MySQL performing the function on this field for every row in the table such that the comparison can be made.
Feel free to use MySQL functions for the comparison value, as those would be calculated just once when the query is being planned. You would then be able to use an index on the field for quickly filtering the rows in the table that meet the criteria. From a query execution standpoint, this is basically that same as if your query has this WHERE clause:
WHERE lbs_agent >= '2016-08-01'
This is as compared to the examples in your question which would be executed as:
WHERE DATE(lbs_date) = '2016-08-03'
and
WHERE MONTH(lbs_date) = 8 AND YEAR(lbs_date) = 2016
Both of these would require full table scan since the values derived from the field are not able to be determined until the row is scanned.
You could try to extract the month, such as EXTRACT(MONTH from NOW())
you can use following code if it timestamp
MONTH(CURDATE())

Comparing date() in sql query

I have 5 records in mysql database and these records have recorded date within this date interval.
$year=2015;
$month=8;
$datefrom=1;
$dateto=31;
$startdate='$year-$month-$datefrom 00:00:00';
$enddate='$year-$month-$dateto 23:59:59';
So I write a query to get these records out like this:
$sql = "SELECT id FROM newpost WHERE email=:email AND :startdate <= poststart <= :enddate AND postapproved=1";
Given that poststart column in table newpost has SQL Datetime format like this: "Y-m-d H:i:s".
But when I changed variable $year = 2016, I still got 5 results? It should return no record. Because those 5 records are recorded between 1 - 31 August 2015.
So I thought I did something wrong in the sql query especially the comparing date part but I could not configure out how to fix it?
Please help!
You can use BETWEEN in your query
$sql = "SELECT id FROM newpost WHERE email=:email AND (poststart BETWEEN :startmonth AND :endmonth) postapproved=1"
Use single quotes to wrap your date values
$sql = "SELECT id FROM newpost WHERE email=:email AND poststart BETWEEN ':startdate' AND ':enddate' AND postapproved=1";
A couple quick things to check to make sure it's not a syntactical error:
Your variable names don't match up. You defined startdate and enddate, but then in the query you used startmonth and endmonth.
You should probably also use leading zeros in your month and day, i.e.:
$month='08';
$datefrom='01';

Insert two date variables into startDate and endDate fields in the table

I want to insert 2 date variables into startDate and endDate fields in the table.
First is $today, next is $today plus $duration.
I have this piece of code which used to work before, but now it does not work
again.
require_once('connection/config.php');
$today = date("y:m:d"); //get today's date
$duration = 14; //get duration
$sql_insert = mysql_query("INSERT INTO adverts (cust_id, startDate, endDate)VALUES('".$today."', (CURDATE()- WeekDay(CURDATE()) +'".$duration."')");
if($sql_insert){echo 'Successful';}else {echo 'Failed';}
This code worked previously. But now, it's not working again.
It does the insert and returns the result for the endDate as '0000-00-00'.
I do not know why it is returning '0000-00-00'.
Please help me.
Thank you all.
You can't just subtract integers from dates in MySQL (that's an Oracle thing).
You need CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY to do what you're trying to do.

SQL to get DISTINCT date values from a table

I have a field in a table named startdate and what I would like to do is run as little queries as possible to obtain a list that would display as the following:
2012
January
March
October
2011
September
November
The only dates that I want to show per year are the dates where there is a record for.
Any help or pointers appreciated.
Thanks
This query can be used to find all distinct Year/Month combinations in a table for a given date (here start date).
SELECT YEAR(startdate) AS DYear, MONTH(startdate) AS DMonth
FROM tablename
GROUP BY YEAR(startdate), MONTH(startdate)
After you have your results back in whatever way you choose to get them you can do something like this:
$year = 0;
while ($row) { //loop through your rows here using while or foreach
if($year != $row['DYear']){
echo '<h1>'.$row['DYear'].'</h1>';
$year = $row['DYear'];
}
echo '<ul>';
echo '<li>'.$row['DMonth'].'</li>';
echo '</ul>';
}
select distinct column1, column2, column3... from table where columnx <> "" order by year, month
Using PDO, you could do something like:
$dbh = new PDO("mysql:dbname=$dbname", $username, $password);
$qry = $dbh->query('
SELECT DISTINCT
YEAR(startdate) AS year,
MONTHNAME(startdate) AS month
FROM
my_table
ORDER BY
startdate
');
if ($qry) {
$row = $qry->fetch();
while ($row) {
$current_year = $row['year'];
echo '<h1>',htmlentities($current_year),'</h1><ul>';
do {
echo '<li>',htmlentities($row['month']),'</li>';
} while ($row = $qry->fetch() and $row['year'] == $current_year);
echo '</ul>';
}
}
SELECT DISTINCT YEAR(startdate), MONTHNAME(startdate)
FROM mytable
ORDER BY YEAR(startdate) desc, MONTH(startdate) asc;
should do the trick, however the output will be:
2012 January
2012 March
2012 October
2011 September
2011 November
you can use the code given by eggyal to convert this into a format that you are looking for. Note that you will need to order on MONTH and not MONTHNAME (unless you want alphabetical order)
As other posts have given your answer, I am going to provide information on why these answers work.
In an SQL select statement you can provide keywords. Specifically for MySQL you can provide ALL, DISTINCT, DISTINCTROW(and others unrelated to distinct rows).
The latter two options are actually the same option and yield the same results. The default select statement with no keyword uses ALL which returns all results. By passing in DISTINCT you eliminate any duplicate entries.
A duplicate entry is an entry where all the fields are the same, However, it should be noted that if you have an auto-incrementing primary key each row is distinct from the last as the pk is different. In order to select a distinct value with this kind of setup, you would need to specify a separate column name that is truly distinct.
For more reading on MySQL SELECT statements refer to the users guide's select section.
Hopefully I didn't provide information you have already gathered from the provided answers, but I have always found understanding "why" and "how" often allow me to understand when a particular solution will work, as well as when it won't work.

MySQL & PHP: summing up data from a table

Okay guys, this probably has an easy answer but has been stumping me for a few hours now.
I am using PHP/HTML to generate a table from a MySQL Table. In the MySQL table (TimeRecords) I have a StartTime and EndTime column. In my SELECT statement I am subtracting the EndTime from the StartTime and aliasing that as TotalHours. Here is my query thus far:
$query = "SELECT *,((EndTime - StartTime)/3600) AS TotalPeriodHours
FROM TimeRecords
WHERE Date
BETWEEN '{$CurrentYear}-{$CurrentMonth}-1'
AND '{$CurrentYear}-{$CurrentMonth}-31'
ORDER BY Date
";
I then loop that through an HTML table. So far so good. What I would like to do is to add up all of the TotalHours and put that into a separate DIV. Any ideas on 1) how to write the select statement and 2) where to call that code from the PHP/HTML?
Thanks in advance!
Try this
$query= "
SELECT ((EndTime - StartTime)/3600) AS Hours, otherFields, ...
FROM TimeRecords
WHERE
Date BETWEEN '{$CurrentYear} - {$CurrentMonth} - 1'
AND '{$CurrentYear}-{$CurrentMonth} - 31' ";
$records =mysql_query($query);
$sum= 0;
while($row=mysql_fetch_array($records))
{
echo"$row['otherFields']";
echo"$row['Hours']";
$sum+=$row['Hours'];
}
echo" Total Hours : $sum ";
Just use a single query with a Sum(). You could also manually calculate it if you're already displaying all rows. (If paginating or using LIMIT, you'll need a separate query like below.)
$query = "
SELECT Sum(((EndTime - StartTime)/3600)) AS SumTotalPeriodHours
FROM TimeRecords
WHERE
Date BETWEEN '{$CurrentYear} - {$CurrentMonth} - 1'
AND '{$CurrentYear}-{$CurrentMonth} - 31'
";
You can do this in the same query if you have a unique id using GROUP BY WITH ROLLUP
$query = "
SELECT unique_id,SUM((EndTime - StartTime)/3600) AS TotalPeriodHours
FROM TimeRecords
WHERE Date BETWEEN '{$CurrentYear}-{$CurrentMonth}-1'
AND '{$CurrentYear}-{$CurrentMonth}-31'
GROUP BY unique_id WITH ROLLUP
ORDER BY Date
";
In this instance the last result from your query with contain NULL and the overall total. If you don't have a unique ID you will need to do it in PHP as per Naveen's answer.
A few comments on your code:
Using SELECT * is not considered good practice. SELECT the columns you need.
Not all months have a day 31 so this may produce unexpected results. If you're using PHP5.3+, you can use
$date = new DateTime();
$endDate = $date->format( 'Y-m-t' );
The "t" flag here gets the last day of that month. See PHP docs for more on DateTime.

Categories