MySQL syntax error when joining tables based on user input - php

I have five tables that produce the results I need, but with five different queries.
Tables are [temperature, partSize, volume, stiffness and weight]. Each table has a column "type" that holds identical values among all tables.
The following queries gives me the results I need...but in five different tables.
$result_temp = mysqli_query($conn, "SELECT * FROM temperature WHERE '%{$_POST['temperature']}%' LIKE '%{$_SESSION['temperature']}%'");
$result_size = mysqli_query($conn, "SELECT * FROM partSize WHERE '%{$_POST['partSize']}%' LIKE '%{$_SESSION['partSize']}%'");
$result_vol = mysqli_query($conn, "SELECT * FROM volume WHERE '%{$_POST['volume']}%' LIKE '%{$_SESSION['volume']}%'");
$result_stiff = mysqli_query($conn, "SELECT * FROM stiffness WHERE '%{$_POST['stiffness']}%' LIKE '%{$_SESSION['stiffness']}%'");
$result_wght = mysqli_query($conn, "SELECT * FROM weight WHERE '%{$_POST['weight']}%' LIKE '%{$_SESSION['weight']}%'");
I need a solution that combines the results of these tables and I am stuck. I keep getting this error: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean
I'm know mySQL will do this and I'm pretty sure it's a simple syntax error but I cannot figure this out.
I've tried this (and many variations...with CONCAT, without CONCAT, tick marks, no tick marks):
$result = mysqli_query($conn, "SELECT * FROM `temperature` WHERE CONCAT ('%{$_POST['partSize']}%') LIKE CONCAT ('%{$_SESSION['partSize']}%') INNER JOIN `partSize` ON temperature.type = partSize.type INNER JOIN `volume` ON partSize.type = volume.type INNER JOIN `stiffness` ON volume.type = stiffness.type INNER JOIN `weight` ON stiffness.type = weight.type ");
The problem seems to arise as soon as I try to INNER JOIN or JOIN the tables. I've spent hours on this already. :/ Can anyone help?

I don't know what version of PHP you're using, but I'd encourage you to switch to PDO and to also use prepared statements (regardless of your version). However the syntax for your statement should be:
SELECT [columns] FROM [first table] INNER JOIN [other tables] ON [first table] WHERE [conditions]
With that being said, take a look at this example:
<?php
$config = array(
'host' => '[db host ip]',
'username' => '[db username]',
'password' => '[db password]',
'name' => '[db name]'
);
$dsn = "mysql:dbname=$config[name];host=$config[host];charset=utf8mb4";
$db = new PDO($dsn, $config['username'], $config['password']);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $db->prepare('
SELECT
*
FROM
`temperature` AS t
INNER JOIN `partSize` AS p ON t.`type` = p.`type`
INNER JOIN `volumne` AS v ON t.`type` = v.`type`
INNER JOIN `stiffness` AS s ON t.`type` = s.`type`
INNER JOIN `weight` AS w ON t.`type` = w.`type`
WHERE
t.`temperature` LIKE CONCAT('%', :temperature, '%') AND
t.`partSize` LIKE CONCAT('%', :partSize, '%') AND
t.`volumne` LIKE CONCAT('%', :volumne, '%') AND
t.`stiffness` LIKE CONCAT('%', :stiffness, '%') AND
t.`weight` LIKE CONCAT('%', :weight, '%');');
// Execute the query passing the $_POST values as the parameters
$stmt->execute(array(
':temperature' => $_POST['temperature'],
':partSize' => $_POST['partSize'],
':volume' => $_POST['volume'],
':stiffness' => $_POST['stiffness'],
':weight' => $_POST['weight']
);
// Get all of the rows returned by the query and store them in an associative array
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

Related

No result found in query

I'm getting an error in my query, and I'm unable to detect the source of the problem.
Here is the query:-
$query = "SELECT useraccount.Username, tariff.Name as tariffs,
sum(energyconsumption.ElecEnergy)
FROM useraccount
INNER JOIN tariff
ON useraccount.tariffs = tariff.id
INNER JOIN energyconsumption
ON energyconsumption.User = useraccount.id
WHERE Date = CURRENT_DATE
GROUP BY useraccount.Username, tariff.Name as tariffs";
Following the query I've code that stores the output in an array:
$result = mysqli_query($conn,$query);
$r = array();
if($result->num_rows){
while($row = mysqli_fetch_array($result)){
array_push($r, array( 'Username' => $row['Username'],
'TariffName' => $row['tariffs'], 'ElecConsump' => $row['ElecEnergy']
));
}
} echo json_encode(array('results' => $r));
Im getting an error in the following line: if($result->num_rows)
This is the output when executing the query:
Notice: Trying to get property of non-object in C:\xampp\htdocs\Project\Client\newone.php on line 22
{"results":[]}
Please note:
This was the output i intially had:
{"results":[{"Username":"absc868","TariffName":"s1","ElecConsump":"2000"},
{"Username":"absc868","TariffName":"s1","ElecConsump":"1900"}]}
But with this new query I have written above, I am trying to produce this output
I am trying to produce the following output:
= {"results":[{"Username":"absc868","TariffName":"s1","ElecConsump":"3900"}
That being, a result set that only has 1 entry, for username, tariff and elecconsump, rather than 2 entries for username, tariff and elecconsump
Thank you once again to all those who have read and contributed to this thread
One problem is the as in the GROUP BY. I would recommend that you use table aliases:
SELECT ua.Username, t.Name as tariffs,
SUM(ec.ElecEnergy) as ElecEnergy
FROM useraccount ua INNER JOIN
tariff t
ON ua.tariffs = t.id INNER JOIN
energyconsumption ec
ON ec.User = ua.id
WHERE Date = CURRENT_DATE
GROUP BY ua.Username, t.Name;

what's wrong with my mysqli join statement syntax

$result = mysqli_query($db, "SELECT * FROM 'category' JOIN 'post-item' ON category.category-id = post-item.category-id");
1 post-item can have 1 category and 1 category can have many post-item.
Change
SELECT * FROM 'category'
JOIN 'post-item' ON category.category-id = post-item.category-id"
to
SELECT * FROM `category`
JOIN `post-item` ON `category`.`category-id` = `post-item`.`category-id`
You have single quote which is not correct
You need to specify particular fields because with * it cannot recognize which fields to fetch and from which table.
So do it something like
"SELECT table1.field1, table1.field2, table2.field4 FROM category JOIN post-item ON category.category-id = post-item.category-id"
Also you can leave out ` or ' while querying through PHP except when you are supplying dynamic variable.

Inner/Left join with two different where clauses

i'm in the process of joining two tables together under two different conditions. For primary example, lets say I have the following nested query:
$Query = $DB->prepare("SELECT ID, Name FROM modifications
WHERE TYPE =1 & WFAbility = '0'");
$Query->execute();
$Query->bind_result($Mod_ID,$Mod_Name);
and this query:
$Query= $DB->prepare("SELECT `ModID` from `wfabilities` WHERE `WFID`=?");
$Query->bind_param();
$Query->execute();
$Query->bind_result();
while ($Query->fetch()){ }
Basically, I want to select all the elements where type is equal to one and Ability is equal to 0, this is to be selected from the modifications table.
I further need to select all the IDs from wfabilities, but transform them into the names located in modifications where WFID is equal to the results from another query.
Here is my current semi-working code.
$Get_ID = $DB->prepare("SELECT ID FROM warframes WHERE Name=?");
$Get_ID->bind_param('s',$_GET['Frame']);
$Get_ID->execute();
$Get_ID->bind_result($FrameID);
$Get_ID->fetch();
$Get_ID->close();
echo $FrameID;
$WF_Abilties = $DB->prepare("SELECT ModID FROM `wfabilities` WHERE WFID=?");
$WF_Abilties->bind_param('i',$FrameID);
$WF_Abilties->execute();
$WF_Abilties->bind_result($ModID);
$Mod_IDArr = array();
while ($WF_Abilties->fetch()){
$Mod_IDArr[] = $ModID;
}
print_r($Mod_IDArr);
$Ability_Name = array();
foreach ($Mod_IDArr AS $AbilityMods){
$WF_AbName = $DB->prepare("SELECT `Name` FROM `modifications` WHERE ID=?");
$WF_AbName->bind_param('i',$AbilityMods);
$WF_AbName->execute();
$WF_AbName->bind_result($Mod_Name);
$WF_AbName->fetch();
$Ability_Name[] = $Mod_Name;
}
print_r($Ability_Name);
See below:
SELECT ModID,
ID,
Name
FROM modifications M
LEFT JOIN wfabilities WF
ON WF.ModID = M.ID
WHERE TYPE =1 & WFAbility = '0'
To do this, you need to join your tables, I'm not quite sure what you are trying to do so you might have to give me more info, but here is my guess.
SELECT ID, Name, ModID
FROM modifications
JOIN wfabilities
ON WFID = ID
WHERE TYPE = '1'
AND WFAbility = '0'
In this version I am connecting the tables when WFID is equal if ID. You will have to tell me exactly what is supposed to be hooking to what in your requirements.
To learn more about joins and what they do, check this page out: MySQL Join
Edit:
After looking at your larger structure, I can see that you can do this:
SELECT modifications.Name FROM modifications
JOIN wfabilities on wfabilities.ModID = modifications.ID
JOIN warframes on warframes.ID = wfabilities.WFID
WHERE warframes.Name = 'the name you want'
This query will get you an array of the ability_names from the warframes name.
This is the query:
"SELECT A.ID, A.Name,B.ModID,C.Name
FROM modifications as A
LEFT JOIN wfabilities as B ON A.ID = B.WFID
LEFT JOIN warframes as C ON C.ID = B.WFID
WHERE A.TYPE =1 AND A.WFAbility = '0' AND C.Name = ?"

Multiple SQL queries and FOREACH - Can be JOINED to one?

I am trying to pull a list of Events, also seeing which members have paid for the Events. I then want to see if they are on the committee, to see if they have admin permissions.
I have successfully done this, using three SQL queries, then using three foreach loops to build the Array.
I am SURE this can be done with one SQL query and one foreach loop, however I have not yet mastered the JOIN technique.
I am using Expression Engine, Codeigniter Active Record, I will display to you the SQL output and also what my current EE functions look like.
THANKS FOR THE HELP! :D
SQL to select ALL events which are active
SELECT `id` as event_ID, `name` as event_name, `description` as event_description
FROM (`events`)
WHERE `events_category_id` = '1'
AND `active` = 1
ORDER BY `name` asc
EE CODE to achieve this:
$query = $this->theDb->select('id as event_ID, name as event_name, description as event_description')
->order_by("name", "asc")
->get_where('events', array('event_category_id'=>$event_type,'active'=>1));
**
SQL to find what EVENT IDs the user has paid for
**
SELECT DISTINCT `products`.`event_ID` as joinedID
FROM (`transactions_items`)
JOIN `transactions` ON `transactions`.`id` = `transactions_items`.`id`
JOIN `products` ON `products`.`id` = `transactions_items`.`product_id`
JOIN `events` ON `events`.`id` = `products`.`event_ID`
WHERE `transactions`.`member_id` = 27500
AND `events`.`active` = 1
AND `event_category_id` = '1'
ORDER BY `events`.`name` asc
EE CODE to achieve this
$query = $this->theDb->select('products.event_ID as joinedID')
->distinct()
->order_by("events.name", "asc")
->join('transactions', 'transactions.id = transactions_items.id')
->join('products', 'products.id = transactions_items.product_id')
->join('events', 'events.id = products.event_ID')
->get_where('transactions_items', array('transactions.member_id' => $memberID, 'events.active' => 1,'activity_category_id'=>$activity_type));
SQL to find ADMIN rights
SELECT `events`.`id` as event_ID, `admins`.`admin_role_id` as role_id, `admins_roles`.`name` as role_description
FROM (`admins`)
JOIN `admins_roles` ON `admins`.`admin_role_id` = `admins_roles`.`id`
JOIN `events` ON `events`.`id` = `admins`.`event_ID`
WHERE `admins`.`member_id` = 27500
AND `events`.`active` = 1
EE CODE to achieve this
$query = $this->theDb->select('events.id as event_ID, admins.admin_role_id as role_id, admins_roles.name as role_description')
->join('admins_roles', 'admins.admin_role_id = admins_roles.id')
->join('events', 'events.id = admins.event_ID')
->get_where('admins', array('admins.member_id' => $memberID, 'events.active' => 1));
FOR EACH LOOPS
// Create list of Events setting defaults
foreach($events_list as $row)
{
$combinedEvents[$row->event_ID] = array(
'eventID' => $row->event_ID,
'eventName' => $row->event_name,
'eventDescription' => $row->event_description,
'isJoined' => 0,
'roleID' => 0,
'roleDescription' => "",
);
}
// Add Committee roles
foreach($admin_list as $row)
{
$combinedEvents[$row->event_ID]['roleID'] = $row->role_id;
$combinedEvents[$row->event_ID]['roleDescription'] = $row->role_description;
}
// Add Transactions
foreach($transaction_list as $row)
{
$combinedEvents[$row->joinedID]['isJoined'] = 1;
}
I don't quite understand the FOREACH part because I've never touched PHP - but you should be able to solve the multiple SQL queires using the ;with clause. I have created an example in response to another question here and here. Is this what you're looking for?

Lots and lots of joins in a Zend Query, hopefully just a slight tweak

Apologies for all this code, anyhow Im re-working a query into the Zend query way of working, this is what I have so far:
$db = Zend_Registry::get ( "db" );
$stmt = $db->query('
SELECT recipe_pictures.picture_id, recipe_pictures.picture_filename, course.course_name, cuisines.name, recipes.id, recipes.Title, recipes.Method, recipes.author, recipes.SmallDesc, recipes.user_id, recipes.cuisine, recipes.course, recipes.Created_at, recipes.vegetarian, recipes.Acknowledgements, recipes.Time, recipes.Amount, recipes.view_count, recipes.recent_ips, guardian_writers.G_item, guardian_writers.G_type
FROM recipes
LEFT JOIN course ON recipes.course = course.course_id
LEFT JOIN recipe_pictures ON recipes.id = recipe_pictures.recipe_id
LEFT JOIN cuisines ON recipes.cuisine = cuisines.id
LEFT JOIN guardian_writers ON recipes.author = guardian_writers.G_author
WHERE recipes.id = ?', $id);
$stmt->setFetchMode(Zend_Db::FETCH_ASSOC);
$recipes = $stmt->fetchAll();
return $recipes;
That one above works, trying to get the Zend version properly, my effort is below.
$db = Zend_Registry::get ( "db" );
$select = $db->select()
->from(array('r' => 'recipes'))
->join(array('c' => 'course'),
'r.course = c.course_id')
->join(array('rp' => 'recipe_pictures'),
'r.id = rp.recipe_id')
->join(array('cui' => 'cuisines'),
'r.cuisine = cui.id')
->join(array('gw' => 'guardian_writers'),
'r.author = gw.G_author')
->where(' id = ? ', $id);
$recipes = $db->fetchRow($select);
return $recipes;
If anyone can spot an error Id be very grateful, thanks
Use joinLeft instead of join to produce left joins.
To fetch specific columns from a table, rather than all (*) use this:
->from(array('r' => 'recipes'), array('id', 'title', 'method'))
or
->joinLeft(array('rp' => 'recipe_pictures'),
'r.id = rp.recipe_id',
array('picture_id', 'picture_filename')
)
To fetch no columns from a table, pass an empty array as the third parameter.
The join method provides an sql INNER JOIN. If you want to get a LEFT JOIN you should use joinLeft.

Categories