Multiple INNER JOIN broke the query - php

I'm trying to join multiple table, let me explain better with my query code example:
if($stmt = $this->db->prepare("SELECT table_users.id AS user_id, table_users.email AS user_email, table_users.GUID as user_guid, "
. "table_roles.slug AS role_slug, table_user_settings.username, table_users.id_roles, "
. "table_users.first_name, table_users.last_name, table_users.mobile_number, table_users.phone_number, "
. "table_users.address, table_users.city, table_users.state, table_users.zip_code, table_users.notes "
. "FROM table_users "
. "WHERE table_users.data = 0 "
. "INNER JOIN table_roles ON table_roles.id = table_users.id_roles "
. "INNER JOIN table_user_settings ON table_user_settings.GUID = table_user.GUID "
. "WHERE table_user_settings.username = ? "
. "WHERE table_user_settings.password = ? "))
{
$stmt->bind_param("ss",$username, $password);
$stmt->bind_result($id, $email, $GUID, $slug, $id_roles, $address, $city, $state, $zip_code, $notes);
$result = $stmt->execute();
$stmt->fetch();
}
var_dump($this->db->error);
$stmt->close();
return $result;
now the error returned from the query is this:
string(226) "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INNER JOIN table_roles ON table_roles.id = table_users.id_roles INNER JOIN table' at line 1"
What is wrong in the query?

You have 3 WHERE clauses in your query, when only 1 is valid and it should go after FROM and INNER JOIN clauses. All conditions in WHERE clause should be separated with AND clause (in this query).
if($stmt = $this->db->prepare("SELECT table_users.id AS user_id, table_users.email AS user_email, table_users.GUID as user_guid, "
. "table_roles.slug AS role_slug, table_user_settings.username, table_users.id_roles, "
. "table_users.first_name, table_users.last_name, table_users.mobile_number, table_users.phone_number, "
. "table_users.address, table_users.city, table_users.state, table_users.zip_code, table_users.notes "
. "FROM table_users "
. "INNER JOIN table_roles ON table_roles.id = table_users.id_roles "
. "INNER JOIN table_user_settings ON table_user_settings.GUID = table_user.GUID "
. "WHERE table_users.data = 0 AND "
. "table_user_settings.username = ? AND "
. "table_user_settings.password = ? "))
You might want to check out the valid SQL syntax in MySql doc: http://dev.mysql.com/doc/refman/5.7/en/select.html

There is a syntax error in your query:
WHERE table_users.data = 0 this should come after JOIN
if($stmt = $this->db->prepare("SELECT table_users.id AS user_id, table_users.email AS user_email, table_users.GUID as user_guid, "
. "table_roles.slug AS role_slug, table_user_settings.username, table_users.id_roles, "
. "table_users.first_name, table_users.last_name, table_users.mobile_number, table_users.phone_number, "
. "table_users.address, table_users.city, table_users.state, table_users.zip_code, table_users.notes "
. "FROM table_users "
. "INNER JOIN table_roles ON table_roles.id = table_users.id_roles "
. "INNER JOIN table_user_settings ON table_user_settings.GUID = table_user.GUID "
. "WHERE table_users.data = 0 AND "
. "WHERE table_user_settings.username = ? AND "
. "WHERE table_user_settings.password = ? "))

Related

Opencart 3 filter products

$sql = "SELECT p.product_id, (SELECT AVG(rating) AS total FROM " . DB_PREFIX . "review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating, (SELECT price FROM " . DB_PREFIX . "product_discount pd2 WHERE pd2.product_id = p.product_id AND pd2.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND pd2.quantity = '1' AND ((pd2.date_start = '0000-00-00' OR pd2.date_start < NOW()) AND (pd2.date_end = '0000-00-00' OR pd2.date_end > NOW())) ORDER BY pd2.priority ASC, pd2.price ASC LIMIT 1) AS discount, (SELECT price FROM " . DB_PREFIX . "product_special ps WHERE ps.product_id = p.product_id AND ps.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priority ASC, ps.price ASC LIMIT 1) AS special";
if (!empty($data['filter_category_id'])) {
if (!empty($data['filter_sub_category'])) {
$sql .= " FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (cp.category_id = p2c.category_id)";
} else {
$sql .= " FROM " . DB_PREFIX . "product_to_category p2c";
}
if (!empty($data['filter_filter'])) {
$sql .= " LEFT JOIN " . DB_PREFIX . "product_filter pf ON (p2c.product_id = pf.product_id) LEFT JOIN " . DB_PREFIX . "product p ON (pf.product_id = p.product_id)";
} else {
$sql .= " LEFT JOIN " . DB_PREFIX . "product p ON (p2c.product_id = p.product_id)";
}
} else {
$sql .= " FROM " . DB_PREFIX . "product p";
}
//FILTRU
$sql .= " INNER JOIN " . DB_PREFIX . "product_option_value ovi ON (p.product_id=ovi.product_id)";
$sql .= " LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' ";
//FILTRU
if (isset($this->request->get['option_value'])) {
foreach ($_GET['option_value'] as $key => $value) {
$sql .= " AND ovi.option_value_id='$value'";
}
}
Where is FILTRU there I insered a code to view in category only products with option_value selected in browser. If i select only one option, it works, but when i have more than 1 option she doesn't select anything.
How i can do to select all products with more options?
All products have minimum 3 option_values.

How to reformat code, adding a new line before a line separator "\n in PhpStorm?

I have this function:
case1:
public function searchArticle($keyword)
{
$keyword = sanitize($keyword, 15);
$sql = "SELECT a.*, c.id as cid, c.name" . Lang::$lang . " as catname, a.title" . Lang::$lang . " as atitle, c.slug as catslug, u.username,"
. "\n (SELECT COUNT(artid) FROM " . self::cmTable . " WHERE artid = a.id) as totalcomments, YEAR(a.created) as year, MONTH(a.created) as month, DATE_FORMAT(a.created, '%d') as day,"
. "\n (SELECT GROUP_CONCAT(DISTINCT participant) FROM " . self::partTable . " WHERE FIND_IN_SET(id,a.participants) > 0)as participants"
. "\n FROM " . self::mTable . " as a"
. "\n LEFT JOIN " . self::ctTable . " as c ON c.id = a.cid" . "\n LEFT JOIN users as u ON u.id = a.uid"
. "\n WHERE MATCH (title" . Lang::$lang . ", body" . Lang::$lang . ") AGAINST ('" . self::$db->escape($keyword) . "*' IN BOOLEAN MODE)"
. "\n AND a.created <= NOW()" . "\n AND (a.expire = '0000-00-00 00:00:00' OR a.expire >= NOW())"
. "\n AND a.active = 1"
. "\n ORDER BY a.created DESC LIMIT 20";
$row = self::$db->fetch_all($sql);
return ($row) ? $row : 0;
}
Every line is as it should be.
Now, when I use code reformat option this code style looks like this:
case2:
public function searchArticle($keyword)
{
$keyword = sanitize($keyword, 15);
$sql = "SELECT a.*, c.id as cid, c.name" . Lang::$lang . " as catname, a.title" . Lang::$lang . " as atitle, c.slug as catslug, u.username," . "\n (SELECT COUNT(artid) FROM " . self::cmTable . " WHERE artid = a.id) as totalcomments, YEAR(a.created) as year, MONTH(a.created) as month, DATE_FORMAT(a.created, '%d') as day," . "\n (SELECT GROUP_CONCAT(DISTINCT participant) FROM " . self::partTable . " WHERE FIND_IN_SET(id,a.participants) > 0)as participants" . "\n FROM " . self::mTable . " as a" . "\n LEFT JOIN " . self::ctTable . " as c ON c.id = a.cid" . "\n LEFT JOIN users as u ON u.id = a.uid" . "\n WHERE MATCH (title" . Lang::$lang . ", body" . Lang::$lang . ") AGAINST ('" . self::$db->escape($keyword) . "*' IN BOOLEAN MODE)" . "\n AND a.created <= NOW()" . "\n AND (a.expire = '0000-00-00 00:00:00' OR a.expire >= NOW())" . "\n AND a.active = 1" . "\n ORDER BY a.created DESC LIMIT 20";
$row = self::$db->fetch_all($sql);
return ($row) ? $row : 0;
}
The closest I can get is to set "Binary expressions" to "wrap always" in "Preferences/Code Style/PHP/Wapping and Braces", but it is still not as it should be and it is not really well readable.
case3:
public function searchArticle($keyword)
{
$keyword = sanitize($keyword, 15);
$sql =
"SELECT a.*, c.id as cid, c.name" .
Lang::$lang .
" as catname, a.title" .
Lang::$lang .
" as atitle, c.slug as catslug, u.username," .
"\n (SELECT COUNT(artid) FROM " .
self::cmTable .
" WHERE artid = a.id) as totalcomments, YEAR(a.created) as year, MONTH(a.created) as month, DATE_FORMAT(a.created, '%d') as day," .
"\n (SELECT GROUP_CONCAT(DISTINCT participant) FROM " .
self::partTable .
" WHERE FIND_IN_SET(id,a.participants) > 0)as participants" .
"\n FROM " .
self::mTable .
" as a" .
"\n LEFT JOIN " .
self::ctTable .
" as c ON c.id = a.cid" .
"\n LEFT JOIN users as u ON u.id = a.uid" .
"\n WHERE MATCH (title" .
Lang::$lang .
", body" .
Lang::$lang .
") AGAINST ('" .
self::$db->escape($keyword) .
"*' IN BOOLEAN MODE)" .
"\n AND a.created <= NOW()" .
"\n AND (a.expire = '0000-00-00 00:00:00' OR a.expire >= NOW())" .
"\n AND a.active = 1" .
"\n ORDER BY a.created DESC LIMIT 20";
$row = self::$db->fetch_all($sql);
return ($row) ? $row : 0;
}
How can I set the code reformat settings in PhpStorm, to force a new line only before . "\n ? (As it can be seen in the case1)
Use the heredoc syntax for the string that contains the query.
You can embed the variables directly into the string (aka variables interpolation). I see you also use class static members and class constants to compose the query and they are not recognized during the string parsing. But you can still embed them using sprintf():
$sql = <<< END_QUERY
SELECT a.*, c.id as cid, c.name%s as catname, a.title%s as atitle, c.slug as catslug, u.username,
(SELECT COUNT(artid) FROM %s WHERE artid = a.id) as totalcomments, YEAR(a.created) as year, MONTH(a.created) as month, DATE_FORMAT(a.created, '%%d') as day,
(SELECT GROUP_CONCAT(DISTINCT participant) FROM %s WHERE FIND_IN_SET(id,a.participants) > 0)as participants
FROM %s as a
LEFT JOIN %s as c ON c.id = a.cid
LEFT JOIN users as u ON u.id = a.uid
WHERE MATCH (title%s, body%s) AGAINST ('%s*' IN BOOLEAN MODE)
AND a.created <= NOW()
AND (a.expire = '0000-00-00 00:00:00' OR a.expire >= NOW())
AND a.active = 1
ORDER BY a.created DESC
LIMIT 20
END_QUERY;
$query = sprintf($query, Lang::$lang, Lang::$lang, self::cmTable, self::partTable, self::mTable, self::ctTable, Lang::$lang, Lang::$lang, self::$db->escape($keyword));
Because the percent sign (%) is a special character for sprintf(), you have to double it in order to let it represent itself (DATE_FORMAT(a.created, '%d') became DATE_FORMAT(a.created, '%%d')).
Or you can avoid using sprintf() if you extract the class static properties, class constants and function calls into local variables before the string:
$lang = Lang::$lang;
$cmTable = Lang::cmTable;
$kword = self::$db->escape($keyword);
// ...
$sql = <<< END_QUERY
SELECT a.*, c.id as cid, c.name{$lang} as catname, a.title{$lang} as atitle, c.slug as catslug, u.username,
// ...
This way the code formatting tools won't touch the query any more. As a bonus, the query is easier to read because it is all text, no more quotes and string concatenation.

PHP MySQL query statement problems

I've been trying to fix this PHP MySQL query all afternoon and am losing my mind! the following query works!:
$sql = "SELECT o.order_id, CONCAT(o.firstname, ' ', o.lastname) AS customer, o.shipping_code, o.total, o.channel, o.currency_code, o.currency_value, o.date_added, o.date_modified, c.image,
cg.name AS cgroup, CONCAT(o.payment_address_1, '<br>', o.payment_city, ', ', o.payment_zone, ' ', o.payment_postcode) AS address, o.telephone AS phone, o.email AS email,
(SELECT os.name FROM " . DB_PREFIX . "order_status os WHERE os.order_status_id = o.order_status_id AND os.language_id = '" . (int)$this->config->get('config_language_id') .
"') AS order_status FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "customer` c ON(o.customer_id=c.customer_id) LEFT JOIN `" . DB_PREFIX . "customer_group_description`
cg ON(c.customer_group_id=cg.customer_group_id)";
but when I try to add the following to it it breaks.
(SELECT action FROM " . DB_PREFIX . "donate_history h LEFT JOIN " . DB_prefix . "order od ON (h.customer_id = od.customer_id)),
I dont if Im writing it right. I've rewritten it, removed parts, tried to make as simple as possible, but I can't fix it. This is what I've been trying :
$sql = "SELECT o.order_id, CONCAT(o.firstname, ' ', o.lastname) AS customer, o.shipping_code, o.total, o.channel, o.currency_code, o.currency_value, o.date_added, o.date_modified, c.image,
cg.name AS cgroup, CONCAT(o.payment_address_1, '<br>', o.payment_city, ', ', o.payment_zone, ' ', o.payment_postcode) AS address, o.telephone AS phone, o.email AS email,
(SELECT action FROM " . DB_PREFIX . "donate_history h LEFT JOIN " . DB_prefix . "order od ON (h.customer_id = od.customer_id)),
(SELECT os.name FROM " . DB_PREFIX . "order_status os WHERE os.order_status_id = o.order_status_id AND os.language_id = '" . (int)$this->config->get('config_language_id') .
"') AS order_status FROM `" . DB_PREFIX . "order` o LEFT JOIN `" . DB_PREFIX . "customer` c ON(o.customer_id=c.customer_id) LEFT JOIN `" . DB_PREFIX . "customer_group_description`
cg ON(c.customer_group_id=cg.customer_group_id)";
Looks like your new subquery you tried adding didn't have an alias.
SELECT o.order_id, CONCAT(o.firstname, ' ', o.lastname) AS customer, o.shipping_code, o.total, o.channel, o.currency_code, o.currency_value,
o.date_added, o.date_modified, c.image, cg.name AS cgroup, CONCAT(o.payment_address_1, '<br>', o.payment_city, ', ', o.payment_zone, ' ', o.payment_postcode) AS address,
o.telephone AS phone, o.email AS email,
(SELECT action
FROM " . DB_PREFIX . "donate_history h
LEFT JOIN " . DB_prefix . "order od
ON (h.customer_id = od.customer_id)) AS donate_history,
(SELECT os.name
FROM " . DB_PREFIX . "order_status os
WHERE os.order_status_id = o.order_status_id AND os.language_id = '" . (int)$this->config->get('config_language_id') .
"') AS order_status
FROM `" . DB_PREFIX . "order` o
LEFT JOIN `" . DB_PREFIX . "customer` c
ON(o.customer_id=c.customer_id)
LEFT JOIN `" . DB_PREFIX . "customer_group_description` cg
ON(c.customer_group_id=cg.customer_group_id)

Data from different tables have the same name, how to retrieve data?

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";

Error Trying to Use "SET #rownum = 0;" in PHP

When I tested this query out in mysql it was fine but when I went to run it in php I keep getting this error.
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT *, (#rownum := #rownum + 1) AS rank FROM ( SELECT *, (totalWins+(total' at line 1
This is the php code I have.
<?php
$sql = " SET #rownum = 0; ";
$sql .= " SELECT *, (#rownum := #rownum + 1) AS rank FROM ( ";
$sql .= " SELECT *, (totalWins+(totalPushs*.5)) AS totalPoints, totalWins+totalLost+totalPushs AS totalBets FROM ( ";
$sql .= " SELECT *, SUM(win) AS totalWins, SUM(lost) AS totalLost, SUM(push) AS totalPushs FROM ( ";
$sql .= " SELECT *, (finalResult = 'Winner') AS win, (finalResult = 'Loser') AS lost, (finalResult = 'Push') AS push FROM ( ";
$sql .= " SELECT " . $db_prefix . "users.userID, userName, ";
$sql .= " IF (pickID=visitorID, visitorResult, homeResult) AS finalResult ";
$sql .= " FROM " . $db_prefix . "users ";
$sql .= " JOIN " . $db_prefix . "picks ";
$sql .= " ON " . $db_prefix . "users.userID = " . $db_prefix . "picks.userID ";
$sql .= " JOIN " . $db_prefix . "schedule ";
$sql .= " ON " . $db_prefix . "picks.gameID = " . $db_prefix . "schedule.gameID ";
$sql .= " ) x ";
$sql .= " ) x ";
$sql .= " GROUP BY userID ";
$sql .= " ) x ";
$sql .= " ) x ";
$sql .= " ORDER BY totalPoints DESC, totalWins DESC, totalPushs DESC, totalLost ";
$result = mysql_query($sql) or die(mysql_error());
while ($row = mysql_fetch_array($result)) {
echo $row[rank] . '|' . $row[userName]. '|' . $row[totalWins] . '|' . $row[totalLost] . '|' . $row[totalPushs] . '|' . $row[totalPoints];
echo '<br>';
}
?>
I can get the php code to work without the first line of code
$sql = " SET #rownum = 0; ";
but it won't echo out the rank column.
Is there something I have to do differently to line one of the code when it's in php?
mysql_query does not support running more than one query at a time. You must first run
mysql_query("SET #rownum = 0;");, then you can run the rest of your query in a second mysql_query call.
Please try tablename.* instead of *

Categories