I'm getting the contents of a column which has contents stored as 3,2 then I'm using the explode function to separate them. The values separated are then used to query another table to bring names. Next I want to implode the results like burger, fries. But the results are not separated by the comma but are like burgerfries... This is what I have done:
$sql = "SELECT items FROM orders";
$result = mysqli_query($connection, $sql);
$array = mysqli_fetch_assoc($result);
$exploded = explode(",", $array['items']);
foreach ($exploded as $row){
$query = "SELECT food_name FROM foodlist WHERE food_id = $row";
$res = mysqli_query($connection, $query);
$arr = mysqli_fetch_assoc($res);
$imploded = implode(", ", $arr);
echo $imploded;
}
Because every $arr only contains one ingredient, so you're actually implode()ing just one element, echoing it, and then echoing other ingredients not separated by anything, so they show together.
You can add them to an array and then implode them:
$sql = "SELECT items FROM orders";
$result = mysqli_query($connection, $sql);
$array = mysqli_fetch_assoc($result);
$exploded = explode(",", $array['items']);
$ingredients = [];
foreach ($exploded as $row){
$query = "SELECT food_name FROM foodlist WHERE food_id = $row";
$res = mysqli_query($connection, $query);
$arr = mysqli_fetch_assoc($res);
$ingredients[] = $arr["food_name"];
}
echo implode(", ", $ingredients);
PRO TIP, it's a bad idea to have your fields separated by a comma like that in the database. You should normalize that field, have another table called ingredients and a pivot table called order_ingredient containing every ingredient a specific order has, then you can simply JOIN the ingredients by ID and get them all at once, instead of doing N+1 queries which will kill your performance fast.
The structure would look like this:
And the query something like
SELECT ingredient FROM orders o JOIN order_ingredient oi ON oi.order_id = o.id JOIN ingredients i ON oi.ingredient_id = i.id
which will return all your ingredients with just one query.
I see that you have already accepted an answer.
If you want to substantially reduce the number of queries you're executing, you could use the following single query to get a comma separated list of food items for all orders.
SELECT o.id, GROUP_CONCAT(f.name SEPARATOR ', ') AS food
FROM orders o
INNER JOIN food f ON FIND_IN_SET(f.id, o.items) > 0
GROUP BY o.id
Here's an SQL fiddle to demonstrate: http://sqlfiddle.com/#!9/b0004c/2
But the correct solution would be to normalize your database structure.
Related
I got an array of ids that I want to use inside an IN statement (sql). However this can only be done when it is written correctly, for example: IN ('12', '13', '14')
How can I change an array of ids into that format? This means adding quotes around every number, and after every number surrounded by quotes a comma, except for the last one in the array.
My code:
$parent = "SELECT * FROM `web_categories` WHERE `parent_id` = 13 AND published = 1";
$parentcon = $conn->query($parent);
$parentcr = array();
while ($parentcr[] = $parentcon->fetch_array());
foreach($parentcr as $parentid){
if($parentid['id'] != ''){
$parentoverzicht .= "".$parentid['id']."";
}
}
I later want to use it like this:
$project = "SELECT * FROM `web_content` WHERE `catid` IN ('".$parentoverzicht."') AND state = 1";
Do this as a single query! SQL engines have all sorts of optimizations for working with tables, and doing the looping in your code is usually way more expensive.
The obvious query for your purposes would be:
SELECT wc.*
FROM web_content wc
WHERE wc.catid IN (SELECT cat.id
FROM web_categories cat
WHERE cat.parent_id = 13 AND cat.published = 1
) AND
wc.state = 1;
Use implode()..
<?php
$a1 = array("1","2","3");
$a2 = array("a");
$a3 = array();
echo "a1 is: '".implode("','",$a1)."'<br>";
echo "a2 is: '".implode("','",$a2)."'<br>";
echo "a3 is: '".implode("','",$a3)."'<br>";
?>
output->>>>>>>
a1 is: '1','2','3'
a2 is: 'a'
a3 is: ''
Have you tried to implode()?
Use ", " as glue. You will have to edit the string yourself to add a " at the beginning and end.
More info: http://php.net/manual/en/function.implode.php
Alternatively you can use single join query, like this.
SELECT con.* FROM `web_content` as con LEFT JOIN `web_categories` as cat
ON con.catid=cat.id WHERE cat.parent_id=13 AND published = 1
If the column's type in the DB is integer you do not actually need to quote the values, but in case it isn't, you can use array_map to quote every item in the array, then implode to join them with commas:
<?php
$ids = [1, 2, 3, 4, 5];
$sql = 'SELECT * FROM mytable WHERE id IN (?)';
$in_clause = array_map(function ($key) {
return "'$key'";
}, $ids);
$sql = str_replace('?', implode(',', $in_clause), $sql);
echo $sql;
Result:
SELECT * from mytable where id in ('1','2','3','4','5')
You can do something like this:
$ids = ['1','2','3','4']; //array of id's
$newArr = array(); //empty array..
foreach($ids as $ids)
{
$newArr[] = "'".$ids."'"; //push id into new array after adding single qoutes
}
$project = "SELECT * FROM `web_content` WHERE `catid` IN (".implode(',',$newArr).") AND state = 1"; /// implode new array with commaa.
echo $project;
This will give you :
SELECT * FROM `web_content` WHERE `catid` IN ('1','2','3','4') AND state = 1
I want to retrieve data from multiple tables using dot operator/join where arguments are passed from an HTML/PHP form.
HTML CODE
<input name="rollno" type="text" placeholder="Roll Number" required>
<input name="submit_view_details" type="submit" value="Proceed">
PHP CODE
if(isset($_POST['submit_view_details']))
{
$rollno = (int) $_POST['rollno'];
$query = "select * from table1, table2 where table1.{$rollno}=table2.{$rollno}";
$result=mysqli_query($connection,$query);
}
In the browser if enter the input 1 and echo this query then it looks like follows:
select * from table1, table2 where table1.1=table2.1
and no row is fetched despite of having data in the table(s).
it only works if the query looks like follows:
select * from table1,table2 where table1.rollno=table2.rollno
However, in that case it fetches all the rows but I need only the row of the rollno that user entered in the above mentioned form.
I am just not able to work this out. Help would be much appreciated. Thanks!
Use the AND keyword to specify the rollno.
SELECT * FROM table1, table2 WHERE table1.rollno = table2.rollno
AND table1.rollno = {$rollno};
You could probably use the keyword JOIN instead like this :
SELECT * FROM table1 NATURAL JOIN table2
WHERE rollno = {$rollno};
You need joins
take a reference of joins from here,
i am sure it will help
http://www.tutorialspoint.com/mysql/mysql-using-joins.htm
You should use join like this
$query = "SELECT tbl1.*, tbl2.*
FROM tbl1
INNER JOIN tbl2 ON tbl1.id = tbl2.id
WHERE tbl1.column = value ";
foreach ($pieces_2 AS $value) {
$pieces_3[] ="(CONCAT_WS('|',$presql2) like '%$value%')"; //concat all columns from one table
}
$serch_jyouken = implode(" and ",$pieces_3); // for multiple keywords
$result1 = mysqli_query($connection, "select p.p_no from pfr_data p where (" .$serch_jyouken .")");
$res1 = array();
while($r1 = mysqli_fetch_array($result1){
$res1[] = $r1['p_no'] ; //fetch primary key from table and store it into array
}
foreach ($pieces_2 AS $value) {
$pieces_4[] ="(CONCAT_WS('|',$presql3) like '%$value%')"; // same as above
}
$serch_jyouken1 = implode(" and ",$pieces_4);
$result2 = mysqli_query($connection, "select p2.p_no from pfr_mod_inform p2 where (" .$serch_jyouken1 .")" );
$res2 = array();
while($r2 = mysqli_fetch_array($result2)){
$res2[] = $r2['p_no'];
}
$res_mrg = array_merge($res1 , $res2); //merge array
$result = implode("','",$res_mrg ); // array to sring
$sql5 = $presql ." from pfr_data p where p.p_no in ('$result') order by p.section_p,p.status,p.no";
I currently have this query with an array that outputs the variables within using a dynamic input in my form (term), this creates a Dynamic Search with auto complete to fill in all of the details for a product.
$return_arr = array();
$param = $_GET["term"];
$fetch = mysql_query("SELECT * FROM crd_jshopping_products WHERE `name_en-GB` REGEXP '^$param'");
while ($row = mysql_fetch_array($fetch, MYSQL_ASSOC)) {
//$row_array['category_id'] = $row ['category_id'];
$row_array['product_id'] = $row['product_id'];
$row_array['product_names'] = $row['name_en-GB'];
$row_array['jshop_code_prod'] = $row['product_ean'];
$row_array['_ext_price_html'] = number_format($row['product_price'],2);
if (!empty($row['product_thumb_image']) AND isset($row['product_thumb_image'])){
$row_array['image'] = $row['product_thumb_image'];
}else {
$row_array['image'] = 'noimage.gif';
}
array_push( $return_arr, $row_array);
}
mysql_close($conn);
echo json_encode($return_arr);
Unfortunately I also need to get the category_id which is not in the same table, I have tried to modify my query as such, but to no avail:
$fetch = mysql_query("SELECT * FROM crd_jshopping_products WHERE `name_en-GB` REGEXP '^$param' AND `crd_jshopping_products_to_categories` = `product_id` ");
What step am I missing here ? The product_id's match in both tables?
try this query instead and try to understand what I have written in it:
$fetch = mysql_query("
SELECT
p.*,
c.category_id
FROM
crd_jshopping_products as p
INNER JOIN crd_jshopping_products_to_categories as c
ON p.product_id = c.product_id
WHERE
`p.name_en-GB` REGEXP '^$param'
");
This means:
SELECT:
Give me everything from p and the category_id from c.
FROM:
Do this from rows in the tables crd_jshopping_products (referred to as p) and crd_jshopping_products_to_categories (referred to as c), where the rows match on the count of p.product_id is the same as c.product_id.
WHERE:
Only return the rows where p.name_en-GB REGEXP '^$param'.
I have database such as
I want to create an associative array such that each att_name value is associated with its possible values from att_value:
array('att_name' => array('att_value_1', 'att_value_2', 'att_value_3'))
What is the best way to achieve this?
While it is easily possible to do this simply by selecting the results you want and iterating them in PHP to create the data structure you want, you could sub some of the work out to MySQL with GROUP_CONCAT():
$query = "
SELECT att_name, GROUP_CONCAT(att_value SEPARATOR ',') AS values
FROM table_name
GROUP BY att_name
";
$result = mysql_query($query);
$array = array();
while ($row = mysql_fetch_assoc($result)) {
$array[$row['att_name']] = explode(',', $values);
}
print_r($array);
Of course, this only works if your values will never contain the character (or sequence of characters) you use for the SEPARATOR in the MySQL query, so the safer pure-PHP way would be:
$query = "
SELECT att_name, att_value
FROM table_name
";
$result = mysql_query($query);
$array = array();
while ($row = mysql_fetch_assoc($result)) {
$array[$row['att_name']][] = $row['att_value'];
}
print_r($array);
Try below:
$sql = "SELECT * from tablename";
$result = mysql_query($sql,$con);
$final_array=array();
while ($row = mysql_fetch_object($result))
{
$final_array[$row->att_name][0]=$row->att_value_1;
$final_array[$row->att_name][1]=$row->att_value_2;
....
....
}
This way :
SELECT
item,
att_name,
GROUP_CONCAT(att_value SEPARATOR "<!>") AS att_value
FROM
table
GROUP BY
att_name
Will give you something like that :
item att_name att_value
-----------------------------
books height 150 mm<!>250 mm
books price rs:20<!>Rs:20
books size 15 pg<!>30 pg<!>60 pg
books width 300 mm<!>400 mm
You have to explode the result from att_value by a <!>. I use this <!> so it highly impossible to have a value inside att_value with this. If you think you would someday use this, take another separator. Example : [{--}], _SEPARATOR_, [_-CUT-_], etc. Something you are sure at 100% you won't use a choice but always as a separator to split the text.
So example :
$SQL = 'SELECT item, att_name, GROUP_CONCAT(att_value SEPARATOR "<!>") AS att_value FROM table GROUP BY att_name';
$Query = mysql_query($SQL) or die('MySQL Error : '.mysql_error());
while($Assoc = mysql_fetch_assoc($Query)){
$Assoc['att_value'] = ($Assoc['att_value'] != '' ? explode('<!>', $Assoc['att_value']) : NULL);
print_r($Assoc);
}
I'm trying to mesh the below mysql query results into a single json object, but not quite sure how to do it properly.
$id = $_POST['id'];
$sql = "SELECT contracts.po_number, contracts.start_date, contracts.end_date, contracts.description, contracts.taa_required, contracts.account_overdue, jobs.id AS jobs_id, jobs.job_number, companies.id AS companies_id, companies.name AS companies_name
FROM contracts
LEFT JOIN jobs ON contracts.job_id = jobs.id
LEFT JOIN companies ON contracts.company_id = companies.id
WHERE contracts.id = '$id'
ORDER BY contracts.end_date";
$sql2 = "SELECT types_id
FROM contracts_types
WHERE contracts_id = '$id'";
//return data
$sql_result = mysql_query($sql,$connection) or die ("Fail.");
$arr = array();
while($obj = mysql_fetch_object($sql_result)) { $arr[] = $obj; }
echo json_encode($arr); //return json
//plus the selected options
$sql_result2 = mysql_query($sql2,$connection) or die ("Fail.");
$arr2 = array();
while($obj2 = mysql_fetch_object($sql_result2)) { $arr2[] = $obj2; }
echo json_encode($arr2); //return json
Here's the current result:
[{"po_number":"test","start_date":"1261116000","end_date":"1262239200","description":"test","taa_required":"0","account_overdue":"1","jobs_id":null,"job_number":null,"companies_id":"4","companies_name":"Primacore Inc."}][{"types_id":"37"},{"types_id":"4"}]
Notice how the last section [{"types_id":"37"},{"types_id":"4"}] is placed into a separate chunk under root. I'm wanting it to be nested inside the first branch under a name like, "types".
I think my question has more to do with Php array manipulation, but I'm not the best with that.
Thank you for any guidance.
Combine the results into another structure before outputting as JSON. Use array_values to convert the type IDs into an array of type IDs. Also, fix that SQL injection vulnerability. Using PDO, and assuming the error mode is set to PDO::ERRMODE_EXCEPTION:
$id = $_POST['id'];
try {
$contractQuery = $db->prepare("SELECT contracts.po_number, contracts.start_date, contracts.end_date, contracts.description, contracts.taa_required, contracts.account_overdue, jobs.id AS jobs_id, jobs.job_number, companies.id AS companies_id, companies.name AS companies_name
FROM contracts
LEFT JOIN jobs ON contracts.job_id = jobs.id
LEFT JOIN companies ON contracts.company_id = companies.id
WHERE contracts.id = ?
ORDER BY contracts.end_date");
$typesQuery = $db->prepare("SELECT types_id
FROM contracts_types
WHERE contracts_id = ?");
$contractQuery->execute(array($id));
$typesQuery->execute(array($id));
$result = array();
$result['contracts'] = $contractQuery->fetchAll(PDO::FETCH_ASSOC);
$result['types'] = array_values($typesQuery->fetchAll(PDO::FETCH_NUM));
echo json_encode($result); //return json
} catch (PDOException $exc) {
...
}
If $contractQuery returns at most one row, change the fetch lines to:
$result = $contractQuery->fetch(PDO::FETCH_ASSOC);
$result['types'] = array_values($typesQuery->fetchAll(PDO::FETCH_NUM));
It would seem like you'd be better served by consolidating the two queries with a JOIN at the SQL level. However, assuming the two arrays have equal length:
for ($x = 0, $c = count($arr); $x < $c; $x++) {
if (isset($arr2[$x])) {
$arr[$x] += $arr2[$x];
}
}
echo json_encode($arr);
Edit: you would need to change from mysql_fetch_object to mysql_fetch_assoc for this to work properly.
Why are you using 2 distinct arrays ? I would simply add the rows of the 2nd query in $arr instead of $arr2. This way, you end up with a single array containing all rows from the 2 queries.