How to combine multiples sum and dates from mysql - php

Im trying to generate data for a graph but everytime i attempt to do it it basically just gives me 1 sum. For the graph i need the date and the value.
This is my current code:
$chart_data = "";
$earnings_query = mysql_query("SELECT SUM(R.rate) as ratess,R.date FROM reports R WHERE R.pid = '$publisher_id' AND R.status = '2'");
if (mysql_num_rows($earnings_query) > 0)
{
while ($row = mysql_fetch_array($earnings_query))
{
$date = date("m/d/Y",strtotime($row['date']));
$chart_data.= '{"date": "'.$date.'", "value": '.$earnings_total['tot'].'},';
}
}
echo $chart_data;
the output is {"date": "12/31/1969", "value": }, but i should be getting daily data all the way back from June 6.
Thanks to all the comments below, the code below solves my problem.
$earnings_query = mysql_query("SELECT SUM(R.rate) as ratess, R.date FROM reports R WHERE R.pid = '$publisher_id' AND R.status = '2' GROUP BY date(R.date)");
if (mysql_num_rows($earnings_query) > 0)
{
while ($row = mysql_fetch_array($earnings_query))
{
$date = date("m/d/Y",strtotime($row['date']));
$chart_data.= '{"date": "'.$date.'", "value": '.$row['ratess'].'},';
}
}
echo $chart_data;

You need a group by clause:
SELECT SUM(R.rate) as ratess, R.date
FROM reports R
WHERE R.pid = '$publisher_id' AND R.status = '2'
GROUP BY R.date;
Without the group by, your query is an aggregation query that runs over the entire set of data. The result (without a group by) is always going to be one row.
If your column called date has a time component, then you might want to use the date() function:
SELECT SUM(R.rate) as ratess, date(R.date) as date
FROM reports R
WHERE R.pid = '$publisher_id' AND R.status = '2'
GROUP BY date(R.date);

Add a GROUP BY date to your SQL command.
SELECT SUM(R.rate) as ratess, R.date
FROM reports R
WHERE R.pid = '$publisher_id' AND R.status = '2'
GROUP BY R.date
This will sum for each date in the range, whereas you were summing for all dates and then selecting the first date. If the date field isn't just a date, but also includes time information, you'll want to use DATE(R.date) instead.

Related

Can not get the required value using sql query in PHP and MySQL

I had one issue with my sql query. I am unable to get the proper data using PHP and Mysql. I am explaining my query below:
$todayDayId = date('N');
if($todayDayId > (int)$day_id) {
$diff = (7-$todayDayId) +(int)$day_id;
}
else {
$diff = (int)$day_id - $todayDayId;
}
$wantedDate = date('Y-m-d', strtotime('+'.$diff.' day'));
$sql="
select
c.cat_id,c.cat_name,c.special,s.subcat_id,s.subcat_name,s.status,s.order_no as order1,c.order_no as ord2, s.cat_id as scatid,b.status,sl.day_id,sl.date_from,sl.date_to
from db_category as c
inner join db_subcategory as s on s.cat_id=c.cat_id
inner join db_restaurant_detail as r on s.subcat_id= r.subcat_id
inner join db_restaurant_basic as b on r.member_id=b.member_id inner join db_special_images as sl on r.day_id=sl.day_id
where
r.day_id='3'
and c.special='2'
and r.city='1'
and (
((sl.date_from IS NULL or sl.date_from='') and (sl.date_to IS NULL or sl.date_to=''))
or (sl.date_from <='2016-12-07' and sl.date_to >= '2016-12-07' )
)
and b.status=1
and s.status=1
group by s.subcat_id
order by cast(ord2 as unsigned), scatid, cast(order1 as unsigned) asc"
$sqlqry = mysqli_query($connect,$sql);
while($row=mysqli_fetch_array($sqlqry)) {
$data[]=array("subcat_id"=>$row['subcat_id'],"subcat_name"=>$row['subcat_name']);
}
The above giving the below output.
[{"subcat_id":"4","subcat_name":"WHISKY"},
{"subcat_id":"60","subcat_name":"SCOTCH"},
{"subcat_id":"63","subcat_name":"RUM"},
{"subcat_id":"56","subcat_name":"BEER"}]
But here my problem is for {"subcat_id":"63","subcat_name":"RUM"} sl.date_from=2016-11-23 and sl.date_to=2016-11-30 but for wantedDate=2016-12-07 the RUM is coming which should not come. Here I need if sl.date_from='' and sl.date_to='' then it can come but if any date is present then it will check. The wanted date should lie in between the given database date.
Please help me.
Thanks in advance.

PHP not storing query result

For a particular query
SELECT MAX(theCount), day
FROM (SELECT FK_Hour, day As day, Count(FK_Hour) As theCount
FROM (Select slottime.FK_Hour, time.day
From slottime INNER JOIN time ON slottime.FK_Hour = time.Hour )
As C GROUP By FK_Hour
)
AS counts GROUP By day
The database returns
However when running the php code
$timequery = array();
try {
$sth = $dbh->prepare("SELECT MAX(theCount), day
FROM (SELECT FK_Hour, day As day, Count(FK_Hour) As theCount
FROM (Select slottime.FK_Hour, time.day
From slottime INNER JOIN time ON slottime.FK_Hour = time.Hour )
As C GROUP By FK_Hour
)
AS counts GROUP By day
");
$sth->execute();
while ($timequery = $sth->fetch(PDO::FETCH_ASSOC)) {
$timequery[] = $results;
}
echo("trying ");
print_r($timequery);
echo(" tried");
}
The output is merely
trying tried
$results seem to be uninitialized... Change code as shown below
while ($results = $sth->fetch(PDO::FETCH_ASSOC))

How to subtract date from MySQL datetime where table is specified as a MySQL function.

I'm using the following 'DATE(time)' to get date from datetime and works with no errors.
SELECT * FROM $t WHERE owner = '$sn' && DATE(time) = '$d';
But then when tables are joint I attempt to use "p.DATE(time)" and I get this error.
FUNCTION p.DATE does not exist. Check the 'Function Name Parsing and Resolution'
Here's the full code where I use "p.DATE(time)".
function get_m_stats($con,$sn,$d=NULL,$t=NULL,$o=NULL){
$get_day = mysqli_query($con, "
SELECT m.* , COUNT(p.sid) frequency FROM music m
JOIN $t p
ON p.sid = m.sid
WHERE p.sid != '' AND p.owner = '$sn' AND p.DATE(time) = '$d'
AND m.perms = 'a'
GROUP BY m.sid
ORDER BY frequency $o
LIMIT 1") or die(mysqli_error($con));
$row_day = mysqli_fetch_array($get_day);
echo $row_day['title'];
}
How do I write this 'p.DATE(time)'?
you are assigning alias to function. just put it on column name
function get_m_stats($con,$sn,$d=NULL,$t=NULL,$o=NULL){
$get_day = mysqli_query($con, "
SELECT m.* , COUNT(p.sid) frequency FROM music m
JOIN $t p
ON p.sid = m.sid
WHERE p.sid != '' AND p.owner = '$sn' AND DATE(p.time) = '$d'
AND m.perms = 'a'
GROUP BY m.sid
ORDER BY frequency $o
LIMIT 1") or die(mysqli_error($con));
$row_day = mysqli_fetch_array($get_day);
echo $row_day['title'];
}
I am sure DATE() is a MySql function - so it cannot exist inside the tabular reference variable p.
Hence the correct way to get your data is getting p.time and then if you want to convert the dateTime to date, use the MySql function DATE.
Hence your query should be :
SELECT m.* , COUNT(p.sid)as frequency
FROM music m JOIN $t p
ON p.sid = m.sid
WHERE p.sid != ''
AND p.owner = '$sn'
AND DATE(p.time) = '$d'
AND m.perms = 'a'
GROUP BY m.sid
ORDER BY frequency $o
LIMIT 1

Complex select statement

I have 4 tables
Tbl_Items:
Asset Id,
Asset_name,
Workshop,
PAT_PASS
(workshop, and PAT_PASS are either YES or NO. Workshop = YES and PAT_PASS = NO means this item is not available for hire..)
Tbl_Project_details:
Project_id,
Project_start_date,
project_end_date
TBL_Project_items:
Project_id,
Asset_id,
Start_date,
End_date
I need to do a select statement that allows me to show all the items in tbl_Items EXCEPT:
1) Those that are already in use on another project on the dates that I need them.
2) Are in the workshop. (Workshop = YES)
3) Are not PAT Tested (PAT_PASS = NO)
So far I have started with a simple statement like this:
$post_project_id = "13-1309.01"; //this is just an example number..
$sql =
"SELECT * FROM Project_details
Where Project_id = '$post_project_id' ";
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result))
{
$hire_start_date = $row['Start_date']; // we find out our projects start date
$hire_end_date = $row['End_date']; // we find out our projects end date
}
$result=mysql_query("SELECT Items.Asset_id, Items.Name
FROM
Items,Project_items
WHERE
Project_details.Start_date < '$hire_start_date'
AND
Project_details.End_date > '$hire_end_date'")
or die(mysql_error());
while($row = mysql_fetch_array($result))
{
// fill up an option box with the results
}
Even this basic script doesn't seem to work! This is the first time I have tried selecting from multiple tables, so this is a steep learning curve!
Thanks!
I would go with a subquery:
SELECT * FROM Tbl_Items AS i WHERE
this should matches your (1.) condition: "take only those records, which with that select dont have any occurences":
0 = (
SELECT COUNT(1) FROM TBL_Project_items AS pi
WHERE i.Asset_Id = pi.Asset_Id
AND Start_date < $hire_start_date
AND End_date > $hire_end_date
)
workshop condition (2.):
AND WORKSHOP != "YES"
pat tested condition (3):
AND PAT_PASS != "NO"
$StartDate and $EndDate are your date constraints:
SELECT ITEM.asset_id,
ITEM.asset_name,
ITEM.workshop,
ITEM.pat_pass
FROM Tbl_Items ITEM
LEFT JOIN Tbl_Project_Items PJITEM
ON PJITEM.asset_id = ITEM.asset_id
AND PJITEM.start_date BETWEEN $StartDate AND $EndDate
OR PJITEM.end_date BETWEEN $StartDate AND $EndDate
WHERE ITEM.workshop = 'no'
AND ITEM.pat_pass = 'yes'
AND PJITEM.asset_id IS NULL
Who's Pat?
One problem:
WHERE
Project_details.Start_date < '$hire_start_date'
AND
Project_details.End_date > '$hire_end_date'")
The columns "Start_date" and "End_date" aren't in the "Project_details" table. In that table, those columns seem to be named "Project_start_date" and "Project_end_date".

How To Optimize PostgreSQL generate_series function

I have a query that uses PostgreSQL generate_series function but when it comes to large amounts of data, the query can be slow. An example of code the generates the query is below:
$yesterday = date('Y-m-d',(strtotime ( '-1 day' ) ));
$query = "
WITH interval_step AS (
SELECT gs::date AS interval_dt, random() AS r
FROM generate_series('$yesterday'::timestamp, '2015-01-01', '1 day') AS gs)
SELECT articles.article_id, article_title, article_excerpt, article_author, article_link, article_default_image, article_date_published, article_bias_avg, article_rating_avg
FROM development.articles JOIN interval_step ON articles.article_date_added::date=interval_step.interval_dt ";
if (isset($this -> registry -> get['category'])) {
$query .= "
JOIN development.feed_articles ON articles.article_id = feed_articles.article_id
JOIN development.rss_feeds ON feed_articles.rss_feed_id = rss_feeds.rss_feed_id
JOIN development.news_categories ON rss_feeds.news_category_id = news_categories.news_category_id
WHERE news_category_name = $1";
$params = array($category_name);
$query_name = 'browse_category';
}
$query .= " ORDER BY interval_step.interval_dt DESC, RANDOM() LIMIT 20;";
This series looks for only content that goes one day back and sorts the results in random order. My question is what are was that generate_series can be optimized to improve performance?
You don't need that generate_series at all. And do not concatenate query strings. Avoid it by making the parameter an empty string (or null) if it is not set:
if (!isset($this -> registry -> get['category']))
$category_name = '';
$query = "
select articles.article_id, article_title, article_excerpt, article_author, article_link, article_default_image, article_date_published, article_bias_avg, article_rating_avg
from
development.articles
inner join
development.feed_articles using (article_id)
inner join
development.rss_feeds using (rss_feed_id)
inner join
development.news_categories using (news_category_id)
where
(news_category_name = $1 or $1 = '')
and articles.article_date_added >= current_date - 1
order by
date_trunc('day', articles.article_date_added) desc,
random()
limit 20;
";
$params = array($category_name);
Passing $yesterday to the query is also not necessary as it can be done entirely in SQL.
If $category_name is empty it will return all categories:
(news_category_name = $1 or $1 = '')
Imho, try removing that random() in your order by statement. It probably has a much larger performance impact than you think. As things are it's probably ordering the entire set by interval_dt desc, random(), and then picking the top 20. Not advisable...
Try fetching e.g. 100 rows ordered by interval_dt desc instead, then shuffle them per the same logic, and pick 20 in your app. Or wrap the entire thing in a subquery limit 100, and re-order accordingly along the same lines.

Categories