I have a mysqli SELECT query that is using an Inner Join and I noticed a big problem: it doesn't select rows where the column value for the condition is null (because NULL doesn't exist in the second table). Here's my code:
<?php
$sql = mysqli_connect(/* CONNECTION */);
$query = "SELECT " .
"e.EQUIPMENT_ID, " .
"e.CUSTOMER_ID, " .
"e.DESCRIPTION, " .
"e.LOCATION, " .
"e.JOB_SITE, " .
"e.PROJECT_NAME, " .
"jb.DESCRIPTION AS JOB_SITE_NAME " .
"FROM equipments e " .
"INNER JOIN jobsites jb ON jb.JOBSITE_ID = e.JOB_SITE " .
"WHERE e.CUSTOMER_ID = 1 ".
"ORDER BY e.EQUIPMENT_ID ASC";
$results = mysqli_query($sql, $query);
if(!isset($data)) $data = array(); $cc = 0;
while($info = mysqli_fetch_array($results, MYSQLI_ASSOC)){
if(!isset($data[$cc])) $data[$cc] = array();
///// FROM TABLE equipments /////
$data[$cc]['EQUIPMENT_ID'] = $info['EQUIPMENT_ID'];
$data[$cc]['DESCRIPTION'] = $info['DESCRIPTION'];
$data[$cc]['LOCATION'] = $info['LOCATION'];
$data[$cc]['PROJECT_NAME'] = $info['PROJECT_NAME'];
$data[$cc]['JOB_SITE_ID'] = $info['JOB_SITE'];
///// FROM TABLE jobsites /////
$data[$cc]['JOB_SITE'] = $info['JOB_SITE_NAME'];
$cc++;
}
print_r($data);
?>
So, as I said, the code returns values but only if the column "JOB_SITE" inside "equipments" has a jobsite id (not null). The ugly solution is to create a row inside the table "jobsites" with a jobsite_id named "empty", but if I can skip this, I will.
Is there a way to join only if e.JOB_SITE is not null ?
You can use LEFT JOIN in SQL query.
$query = "SELECT " .
"e.EQUIPMENT_ID, " .
"e.CUSTOMER_ID, " .
"e.DESCRIPTION, " .
"e.LOCATION, " .
"e.JOB_SITE, " .
"e.PROJECT_NAME, " .
"jb.DESCRIPTION AS JOB_SITE_NAME " .
"FROM equipments e " .
"LEFT JOIN jobsites jb ON jb.JOBSITE_ID = e.JOB_SITE " .
"WHERE e.CUSTOMER_ID = 1 ".
"ORDER BY e.EQUIPMENT_ID ASC";
This query will return NULL VALUE for column JOB_SITE_NAME if there is no row matching jb.JOBSITE_ID in equipments table
Related
First off, I am fairly new to coding. I try to do my due diligence before coming here for advice.
I am trying to write a function that will query the database for a users numbers and get the average for each user.
function getUserAverage($userID) {
//loop through user totals & calculate average for each user
$sql = "select p.userID, p.user, p.number ";
$sql .= "from " . DB_PREFIX . "numbers p ";
$sql .= "inner join " . DB_PREFIX . "users u on p.userID = u.userID ";
$sql .= "where u.userID = " . $user->userID . " ";
$sql .= "order by u.lastname, u.firstname";
$query = $mysqli->query($sql);
while ($row = $query->fetch_assoc()) {
//player average of numbers
$tba = ROUND(AVG(`number`),2);
}
$query->free;
return $tba;
}
The result I am hoping to get is something like:
user1 = 14.5
user2 = 35.8
user3 - 7.4
I have written code to get the average numbers for all, but the need is to get by individual user.
//Average Numbers
$sql_avgNum = "SELECT ROUND(AVG(`number`),2) AS `Average` \n"
. "FROM `" . DB_PREFIX . "numbers` \n";
$data = $mysqli->query($sql_avgNum);
$result_avgNum = mysqli_fetch_array($data);
echo ' <tr class="altrow"><td> Average Number: </td><td> ' .
$result_avgNum[0] . ' </td></tr>';
//End Average Numbers
for count average of individual data you must do it using group by. Further reference of group by is here:
I'm not very sure, but I think that this is what you're looking for:
function getUserAverage($userID) {
// loop through user totals & calculate average for each user
$sql = "SELECT p.userID, u.user, AVG(p.number) AS 'avarage' ";
$sql .= "FROM " . DB_PREFIX . "numbers p ";
$sql .= "INNER JOIN " . DB_PREFIX . "users u ON(p.userID = u.userID) ";
$sql .= "WHERE p.userID = " . $user->userID . " ";
$sql .= "GROUP BY p.userID ";
$sql .= "ORDER BY u.lastname, u.firstname";
$query = $mysqli->query($sql);
while ($row = $query->fetch_assoc()) {
//player average of numbers
$tba = $row['avarage'];
}
$query->free;
return $tba;
}
I am trying to optimize some of my code and i believe i need an if/else or case to do this, however I think i would need php in the query to get it to work
here is the code I am trying to optimize
$sql = "SELECT value, COUNT(*) AS count
FROM sodsurvey LEFT OUTER JOIN age
ON sodsurvey.age_id = age.id
WHERE value IS NOT NULL AND office_id = " . $office_id . "
GROUP BY age_id; ";
if ($_SESSION['filteryear'] != 0 && $_SESSION['filtermonth'] != 0) {
$sql = "SELECT value, COUNT(*) AS count
FROM sodsurvey LEFT OUTER JOIN age
ON sodsurvey.age_id = age.id
WHERE value IS NOT NULL AND office_id = " . $office_id . "
AND year = " . $_SESSION['filteryear'] . " AND month = " . $_SESSION['filtermonth'] . "
GROUP BY age_id; ";
} else if ($_SESSION['filteryear'] != 0 || $_SESSION['filtermonth'] != 0) {
$sql = "SELECT value, COUNT(*) AS count
FROM sodsurvey LEFT OUTER JOIN age
ON sodsurvey.age_id = age.id
WHERE value IS NOT NULL AND office_id = " . $office_id . "
AND (year = " . $_SESSION['filteryear'] . " OR month = " . $_SESSION['filtermonth'] . ")
GROUP BY age_id; ";
}
and this is what I have tried to give you a rough idea of what I am trying to achieve
$filter = "";
if ($_SESSION['filteryear'] != 0 && $_SESSION['filtermonth'] != 0) {
$filter = "AND year = " . $_SESSION['filteryear'] . " AND month = " . $_SESSION['filtermonth'] . ""
} else if ($_SESSION['filteryear'] != 0 || $_SESSION['filtermonth'] != 0) {
$filter = "AND (year = " . $_SESSION['filteryear'] . " OR month = " . $_SESSION['filtermonth'] . ")"
}
$sql = "SELECT value, COUNT(*) AS count
FROM sodsurvey LEFT OUTER JOIN age
ON sodsurvey.age_id = age.id
WHERE value IS NOT NULL AND office_id = " . $office_id . "
CASE
WHEN ".isset($filter)." THEN ". $filter ."
END
GROUP BY age_id; ";
You can build up an array of filters depending on which values (year, month, etc) are set, and then combine them all into the WHERE clause. You don't need to worry about all the separate cases where both are set, or one are set, and so on.
I would also strongly echo the advice above that recommended looking into prepared statements, but this will hopefully get you on your way.
<?php
$office_id = 10;
$_SESSION['filteryear'] = 2016;
$_SESSION['filtermonth'] = 12;
$filters = [
"value IS NOT NULL",
"office_id = {$office_id}",
];
if ($_SESSION['filteryear']) {
$filters[] = "year = {$_SESSION['filteryear']}";
}
if ($_SESSION['filtermonth']) {
$filters[] = "month = {$_SESSION['filtermonth']}";
}
$sql = "
SELECT value, COUNT(*) AS count
FROM sodsurvey
LEFT JOIN age ON sodsurvey.age_id = age.id
WHERE " . implode(' AND ', $filters) . "
GROUP BY age_id;
";
The implode line combines each filter that's been set into a single WHERE clause.
is it valid to use PHP with a case in my attempt above?
No. PHP code cannot be part of your SQL query, however your PHP code can generate SQL query
In MySQL, I am trying to find a way to optimize my code
Just make your SQL code generated by PHP code based on all the conditions. You can easily concatenate strings being partions of your query conditionally.
I'm attempting to select a query to use based on the number of rows returned by a test result.
$id = mysql_real_escape_string(htmlspecialchars($_POST['id']));
$result = "SELECT FROM Notifications WHERE UserID=$id";
$r = e_mysql_query($result);
$row = mysql_fetch_array($r);
$num_results = mysql_num_rows($result);
$result = '';
if ($num_results != 0) {
$result =
"SELECT U.UserID,U.FirstName,U.LastName, " .
" DATE_FORMAT(U.BirthDate,'%m-%d-%Y') AS BirthDate, " .
" N.Email, N.Phone,N.ProviderName, N.SubNotifications " .
" FROM Users U, Notifications N " .
" WHERE U.LocationID=0 " .
" AND N.UserID='$id'";
} else {
$result =
"SELECT UserID, FirstName, LastName," .
" DATE_FORMAT(BirthDate, '%m-%d-%Y') AS BirthDate " .
" FROM Users " .
" WHERE LocationID = 0 " .
" AND UserID ='$id'";
}
echo $result;
e_mysql_result($result); //Bastardized/homegrown PDO
if ($row = mysql_fetch_assoc($result)) {
$retValue['userInfo'] = $row;
...
I'm checking the Notifications table to see if the UserID exists there, if it doesn't it loads what does exist from the Users table, if it does, then it loads everything from the Notifications table.
I'm echoing out the $result and the proper statement is loaded, but it doesn't execute. When I run the concatenated query I get from the PHP preview, it returns just fine.
Before I had to if/else this, I was running the first query, loading everything from the Notifications table, and it was loading just fine. What am I missing?
You can do the whole thing with one query with a LEFT JOIN.
$query= "SELECT U.UserID, U.FirstName,U.LastName, " .
" DATE_FORMAT(U.BirthDate,'%m-%d-%Y') AS BirthDate, " .
" N.Email, N.Phone,N.ProviderName, N.SubNotifications " .
" FROM Users U " .
" LEFT JOIN Notifications N " .
" ON U.UserID = N.UserID " .
" WHERE U.UserID = '$id'";
You are missing execute a query with mysql_query() on all $result
Also change (query variable should be quoted) so change your all variables $id quoted
$result = "SELECT FROM Notifications WHERE UserID=$id";
to
$result = "SELECT FROM Notifications WHERE UserID='$id'";
$r = mysql_query($result);
Note :- mysql_* has been deprecated use mysqli_* or PDO
Here is my code:
$sql = "SELECT table1.Insert_ID, table1.Type, table1.Date "
. "table2.User, table2.Date "
. "FROM Insert AS table1 "
. "INNER JOIN Contact AS table2 ON table2.Contact_ID = table1.Contact_ID";
$x =0;
while($row = odbc_fetch_array($res)){
$x++;
$values= ($x . ": " . " Insert ID:". $row['Insert ID'] . " Date Created: " . $row['Date'] . " Date Modified:" . "\n");
print($values);
}
I want Date from both table1 and table2, how do I proceed to retrieve the data if they both have the same name?
Use an alias.
SELECT table1.Insert_ID, table1.Type, table1.Date as Date1 "
. "table2.User, table2.Date as Date2 "
. "FROM Insert AS table1 "
. "INNER JOIN Contact AS table2 ON table2.Contact_ID = table1.Contact_ID";
Column aliases.
$sql = "SELECT table1.Insert_ID, table1.Type, table1.Date as T1Date "
. "table2.User, table2.Date as T2Date"
. "FROM Insert AS table1 "
. "INNER JOIN Contact AS table2 ON table2.Contact_ID = table1.Contact_ID";
This is the original MySQL query:
UPDATE jos_bully_table AS jbt1
INNER
JOIN ( SELECT jbt2.bully_concat_name,
COUNT(*) AS b_name_count
FROM jos_bully_table AS jbt2
GROUP
BY jbt2.bully_concat_name
) AS jbt3
ON jbt3.bully_concat_name = jbt1.bully_concat_name
SET jbt1.b_name_count = jbt3.b_name_count
;
It works great when running from phpMyAdmin. I clicked Create PHP Code and this is generated:
$sql = "UPDATE jos_bully_table AS jbt1\n"
. " INNER\n"
. " JOIN ( SELECT jbt2.bully_concat_name,\n"
. " COUNT(*) AS b_name_count\n"
. " FROM jos_bully_table AS jbt2\n"
. " GROUP\n"
. " BY jbt2.bully_concat_name\n"
. " ) AS jbt3\n"
. " ON jbt3.bully_concat_name = jbt1.bully_concat_name\n"
. " SET jbt1.b_name_count = jbt3.b_name_count\n"
. "";
I'm trying to run the same query from a php file, but the db isn't updating.
Here is my php file:
<?php
$database = "xxxxxxxxx" ;
$username = "xxxxxxxxx" ;
$password = "xxxxxxxxx" ;
mysql_connect(localhost,$username,$password);
#mysql_select_db($database) or die( "Unable to select database");
mysql_query($sql);
$sql = "UPDATE jos_bully_table AS jbt1\n"
. " INNER\n"
. " JOIN ( SELECT jbt2.bully_concat_name,\n"
. " COUNT(*) AS b_name_count\n"
. " FROM jos_bully_table AS jbt2\n"
. " GROUP\n"
. " BY jbt2.bully_concat_name\n"
. " ) AS jbt3\n"
. " ON jbt3.bully_concat_name = jbt1.bully_concat_name\n"
. " SET jbt1.b_name_count = jbt3.b_name_count\n"
. "";
echo "<!-- SQL Error ".mysql_error()." -->";
?>
What is wrong with this?
You're running your query string BEFORE you defined it.
$sql = "SELECT ..."
$result = mysql_query($sql) or die(mysql_error());
As well, look into HEREDOCs for defining multi-line strings:
$sql = <<<EOL
SELECT ..
FROM ...
WHERE ...
ORDER BY ..
EOL;
is far more readable than a multi-line concatenation