I am trying to do a MYSQL LEFT JOIN query, however I'm getting an error:
"Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in". Because the query which is returned is false.
The code is:
$query = "
SELECT a.page
, SUM(b.views) views
, ROUND(SUM(b.costs)/1.38,2) costs
, ROUND(SUM(a.amount),2) REV
, ROUND(SUM(a.amount) - SUM(b.costs)/1.38,2) PNL
FROM revenues a
LEFT
JOIN costs b
ON a.page = b.page
WHERE a.date BETWEEN '$start_date' AND '$end_date'
AND a.country = '$country'
AND b.date BETWEEN '$start_date' AND '$end_date'
GROUP
BY a.page";
$result = mysqli_query($connection,$query);
if ($result != false) {
$foundnum = mysqli_num_rows($result);
if ($foundnum == 0) {
echo 'No results found.';
}
} else {
echo 'returned false';
}
printQuery($result);
printQuery is a function of me which creates a html table.
If I do two seperate queries on the tables I get correct tables back. My seperate queries are:
$query = "SELECT page, round(sum(amount),2) as REV FROM revenues WHERE date between '$start_date' AND '$end_date' AND country = '$country' GROUP BY page" ;
$query2 = "SELECT page, sum(views) as views, round(sum(costs)/1.38,2) as costs FROM costs WHERE date between '$start_date' AND '$end_date' GROUP BY page";
Can someone please point to me where the mistake is.
Table revenues consists of the columns:
date: date
amount: float (NULL if no revenue was made)
country: varchar
Table costs cosists of the columns:
date: date
costs: float (always >= 0)
views: int
Thanks
The following is usless:
else {
echo 'returned false';
}
Replace it with something like:
else {
echo "Query failed.\nMySQLi error: " . mysqli_error();
}
You get points for at least checking your return values, but you need to make your code fail descriptively at least for dev purposes.
Related
I am making a site where you can make posts and read post and now I am writing some code to filter these posts (like sort by 'new' or 'most liked')
I have this as query:
$search_query="SELECT Posts.user, Posts.title, Games.name,
Posts.text, Posts.time, Posts.attachement
FROM Posts
INNER JOIN Games ON Posts.game = Games.id
WHERE Posts.game = '$game'
AND tag = '$tag' AND subtag = '$subtag'"
or die("The search_query on the database has failed!");
The normal $search_query works fine.
Now I want to extend this query if the user wants to sort the posts, for example posts of last week, day etc.:
if(!empty($_POST['time']))
{
$search_query= "SELECT * FROM $search_query
WHERE time < DATE_SUB(now(), INTERVAL $time)";
}
But this query doesn't work, cause I get this error:
mysqli_num_rows() expects parameter 1 to be mysqli_result, bool given in
I have read that this means that there is error in the query.
Does anyone know how I can fix this?
All you need to do is simply add the additional clauses to the existing WHERE
if(!empty($_POST['time']))
{
$search_query .= " AND time < DATE_SUB(now(), INTERVAL $time)";
}
PS the or die() on here makes no sense as you are only putting text into a string variable, not executing it.
$search_query="SELECT Posts.user, Posts.title, Games.name,
Posts.text, Posts.time, Posts.attachement
FROM Posts
INNER JOIN Games ON Posts.game = Games.id
WHERE Posts.game = '$game'
AND tag = '$tag' AND subtag = '$subtag'"
or die("The search_query on the database has failed!");
The sql calc found rows in mysqli is not returning the exact number of records (numrange). I get : 1. It should work fine.
$sQuery1 = "SELECT SQL_CALC_FOUND_ROWS
sv_cam.image,
sv_cam.cam_id,
sv_cam.alt,
sv_orte.resort,
sv_orte.resort_us,
sv_country.sym,
DATE_FORMAT(sv_cam.lud, '%b %d') as stat
FROM sv_cam
LEFT JOIN sv_orte ON sv_cam.res_id = sv_orte.res_id AND status=0
INNER JOIN sv_canton ON sv_orte.can_id = sv_canton.can_id
INNER JOIN sv_country ON sv_canton.cou_id = sv_country.cou_id
WHERE (lud >= DATE_SUB('$today', INTERVAL 30 DAY)) ORDER BY lud desc, sv_cam.cam_id desc LIMIT $offset, $cams";
//echo $sQuery1;
$sResult1=mysqli_query($conn, $sQuery1);
$numrows = mysqli_num_rows($sResult1);
//if ($numrows<1) { exit; }
$numrange=mysqli_query($conn,"SELECT FOUND_ROWS()");
echo $numrange;
mysql_query() function returns the mysqli_result object. Therefore you need to fetch your results.
$sResult2 = mysqli_query($conn, 'SELECT FOUND_ROWS() AS total');
$found_rows = mysqli_fetch_object($sResult2);
echo 'total rows'.$found_rows->total;
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.
I have two tables, users and clients_closed_1.
I need to order the result by the count of the rows on the table client_closed_1 where meeting=1.
I did it for time_closed field but that was easy because there was no condition.
It's a part of a search code so I'll show you all of it.
With this code I manage to order it by meeting - but users who has no rows with meeting=1 isn't pull out from the database and I need them to show even if they doesn't have meetings.
if (project_type($_GET['project']) == 1) {
$table = 'clients_closed_1';
} else {
$table = 'clients_closed_2';
}
$s_query = "SELECT *,COUNT(time_closed) as numc FROM `".$table."` FULL JOIN `users` ON users.ID=user_c WHERE 1=1";
if (isset($_POST['search'])) {
if ($_POST['tm'] == 'da') {
$dd = strtotime($_POST['y']."-".$_POST['m']."-".$_POST['d']);
$s_query = $s_query." && DATE(FROM_UNIXTIME(time_closed)) = DATE(FROM_UNIXTIME(".$dd."))";
}
elseif ($_POST['tm'] == 'mon') {
$s_query = $s_query." && YEAR(FROM_UNIXTIME(time_closed))=".$_POST['y']." && MONTH(FROM_UNIXTIME(time_closed))=".$_POST['m'];
}
if (!empty($_POST['search_name'])) {
$s_query = $s_query." && CONCAT(p_name,' ',l_name) LIKE '%".$_POST['search_name']."%'";
}
if (!empty($_POST['level'])) {
$query = "&& (level=3 && project IN (SELECT `project` FROM `project` WHERE type='2')) || level=4";
}
} else {
$s_query = $s_query." && YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW()) && MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())";
}
if (isset($_GET['order'])) {
if ($_GET['order'] == 'closing') {
$s_query = $s_query." GROUP BY users.ID ORDER BY numc DESC";
}
elseif ($_GET['order'] == 'meeting') {
$s_query = $s_query." && meeting='1' GROUP BY users.ID ORDER BY numd DESC";
}
}
$query = $db->query($s_query);
If you need any more code/doedn't understand something comment please and I'll fix it.
Thank you.
EDIT:
example of $s_query:
SELECT *,COUNT(time_closed) as numc, COUNT(meeting) as numd FROM `clients_closed_1`
FULL JOIN `users` ON users.ID=user_c WHERE 1=1 &&
YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW()) &&
MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())
GROUP BY users.ID ORDER BY numc DESC
Im not sure I understand 100% of the criteria youre looking for but here is a rough draft of the query:
SELECT c.id, c.meeting, temp1.time_closed_count, temp2.meeting_count, temp3.status_count
FROM `clients_closed_1` c
FULL JOIN `users` u
ON c.user_c=u.ID
LEFT JOIN (SELECT time_closed, count(time_closed) time_closed_count FROM clients_closed_1 GROUP BY time_closed) temp1
ON c.time_closed = temp1.time_closed
LEFT JOIN (SELECT meeting, count(meeting) meeting_count FROM clients_closed_1 GROUP BY meeting) temp2
ON c.meeting = temp2.meeting
LEFT JOIN (SELECT status, count(status) status_count FROM clients_closed_1 GROUP BY status) temp3
ON c.status = temp3.status
WHERE 1=1
AND YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW())
AND MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())
ORDER BY {$order_criteria} DESC
Whats happeneing here is, we are doing the count of all distinct meeting values in a subquery and joining it to the original query based on the value of "meeting" for each row.
This gives us the total "meetings" grouped by distinct meeting values, without cutting out rows. Such is the same for the other 2 subqueries.
This also cleans things up a bit and allows us to just insert the $order_criteria, where that could be time_closed count, meeting_count, or status_count. Just set a default (id) in case your user does not choose anything :)
Edit: Id also recommend trying to get out of the SELECT * habit. Specify the columns you need and your output will be much nicer. Its also far more efficient when you start dealing with larger tables.
After I wrote a really long query to do this I found the perfect soulution.
SELECT SUM(IF(meeting='1' && user_c=users.ID, 1,0)) as meeting_count FROM clients_closed_1 JOIN users
This query return as meeting_count the number of meeting which their value is '1'.
I didn't know I can do such thing until now, so I shared it here. I guess it can be helpull in the future.
I have a couple tables where there is a same field added. What I want to do is get the earliest year from all these records.
Tables:
comics | movies | tv | tv_episodes
Code So Far (Doesn't Work):
function getStartYear() {
include("config.php");
$query = "SELECT DATE_FORMAT(added, '%Y') as `added` FROM (comics,movies,tv,tv_episodes) ORDER BY `added` DESC LIMIT 1";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
return $row['added'];
}
}
Error Returned:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in E:\xampp\htdocs\mydb\functions\common.php on line 94
What would be the most efficient way to do this?
UPDATE
So going by Andrew's answer the new query looks like:
function getStartYear() {
include("config.php");
$query = "SELECT MIN(y) FROM (
SELECT MIN(YEAR(added)) AS y FROM comics
UNION SELECT MIN(YEAR(added)) AS y FROM movies
UNION SELECT MIN(YEAR(added)) AS y FROM tv
UNION SELECT MIN(YEAR(added)) AS y FROM tv_episodes
) AS t1";
$result = mysql_query($query);
if (mysql_num_rows($result) > 0) {
$finalanswer = mysql_fetch_array($result);
return $finalanswer['t1']; // <-- Line 96
}else{
echo mysql_error();
}
}
New Message:
Notice: Undefined index: t1 in E:\xampp\htdocs\mydb\functions\common.php on line 96
Could retrieve it through SQL using a UNION sub-query:
SELECT MIN(y) FROM (
SELECT MIN(YEAR(added)) AS y FROM table1
UNION SELECT MIN(YEAR(added)) AS y FROM table2
...
) AS t1;
First you should be checking to make sure your SQL statement actually returns the desired data. Run the script itself in some sort of SQL viewer (or phpMySQL), or
echo mysql_error();
just to be sure you don't have an invalid SQL statement.
The invalid resource error you're getting indicates to me that the "$result" of your mysql_query function is not a valid resource.
So:
if (!$result = mysql_query($query))
echo mysql_error();
if you do have an error in your query, diagnose and fix and go from there...
As it stands right now, you're doing a "return" from the middle of a loop, which means you're returning the first object found in the result set.
I would consider instead of "looping", do this:
if (mysql_num_rows($result) > 0)
{
$finalanswer = mysql_fetch_array($result);
return $finalanswer['added'];
}
else
echo mysql_error();
error trapping is kind of a nice thing to get in the habit of. :)