Store Multidimensional Array in Mysql PHP Code - php

Hi guys just want to ask how can i store multidimensional array in mysql?
My table format is like this:
Sales Table
| sales id | fkmember | date_of_sales
Sales Line Table
| line id | fkproduct | fksales | qty_purchased
My array is this:
foreach($products as $element => $inner_array){
echo "<strong>Product ID: ".$element."</strong><br>";
foreach($inner_array as $items){
echo $items."<br>";
}
}
How can i put the data in my tables?

You can try serialization of array, very similar to what Wordpress does, to store configuration values

Use implode() function which turns the array of column values into a string.
foreach($inner_array as $items) {
$sql = "INSERT INTO Sales (salesid, fkmember, date_of_sales, lineid, fkproduct, fksales, qty_purchased ) VALUES ('" . implode("', '", $items) . "')";
$result = mysql_query($sql) or die(mysql_error());
}

Related

Request returns Array

Table:
id | date | number
----------------------
1 | 01.01 | 12
2 | 02.01 | 15
3 | 03.01 | 174
4 | 04.01 | 14
5 | 05.01 | 65
6 | 06.01 | 78
7 | 07.01 | 69
8 | 08.01 | 147
9 | 09.01 | 12
10 | 10.01 | 87
I'm trying to output last 7 values from date ordered by id with some implode.
$day=$mysqli->query("SELECT `date` FROM `online` ORDER BY `id` DESC LIMIT 7");
$day=$day->fetch_all();
$day="'". implode("', '", $day) . "'";
echo $day;
echo returns 'Array', x7. How to output '01.01','02.01', etc.?
First of all, your code uses $day to store at least three different things during its lifetime. While the compiler doesn't complain, it is confusing and difficult to understand for humans. Let rewrite your code to use different variables for different items:
$result = $mysqli->query("SELECT `date` FROM `online` ORDER BY `id` DESC LIMIT 7");
$days = $result->fetch_all();
$text = "'" . implode("', '", $days) . "'";
echo $text;
A quick print_r($days) will reveal you that the value returned by $result->fetch_all(); is a two-dimensional array. Each of its items is an array, one row from the result set.
There are many ways to get the date column of each row returned by $result->fetch_all(). The way that is the easiest to read and understand is to ask mysqli_result::fetch_all() to return the rows as associative arrays indexed by column names (by default it returns arrays numerically indexed) then use the function array_column() to get only the values of the date column and pass only them to implode().
The code is like this:
$result = $mysqli->query("SELECT `date` FROM `online` ORDER BY `id` DESC LIMIT 7");
$days = $result->fetch_all(MYSQLI_ASSOC);
$text = "'" . implode("', '", array_column($days, 'date')) . "'";
echo $text;
The next step towards readability (with a small performance penalty) and correctness is to quote each day individually before joining them into the final string. The function array_map() can be used for that; it applies a callback function to each item of the passed array and returns a new array that contains the values returned by the callback function.
$result = $mysqli->query("SELECT `date` FROM `online` ORDER BY `id` DESC LIMIT 7");
$days = $result->fetch_all(MYSQLI_ASSOC);
$text = implode(', ', // Join the quoted days with commas
array_map(
function($day) {
return "'{$day}'"; // Put each day in single quotes
},
array_column($days, 'date') // Get only the 'date' column
)
);
echo $text;
A quick test with a query that doesn't return any result (use an empty table or add an impossible WHERE condition) reveals that this code doesn't produce any output (which is correct since there is no data retrieved from the database) while the original code produces an empty pair of apostrophes (''), which is not correct (let's remember the requirement was to put each day in single quotes and separate the days with comma and a space.)
Issue is $day->fetch_all() generate associative array and implode doesn't support associative arrays
Try:
$sql = "SELECT `date` FROM `online` ORDER BY `id` DESC LIMIT 3";
$result = $conn->query($sql);
$day = [];
while($row = $result->fetch_row()) {
$day[]=$row[0]; }
$day="'". implode("', '", $day) . "'"; echo $day;
Each element in the fetched array is an array of its columns.
One way to unravel it with with an array_map call:
$first = function($arr) {
return $arr[0];
};
$day = $day->fetch_all();
$day = array_map($first, $day);
$day = "'". implode("', '", $day) . "'";
echo $day;
Without any additional php functions, just pure MySql approach:
$result = $mysqli->query("SELECT group_concat(`date` separator ', ') as dates
FROM `online` ORDER BY `id` DESC LIMIT 7");
$days = $result->fetch_assoc(); // $days['dates'] contains the needed string
https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat
To see if what you have is what you want, begin to replace :
echo $day;
With :
print_r($day);
If you see what you want, it's that your SQL request works well. Next, navigate in arrays like #Mureinik says.
If you want a cleaner display, you can use :
echo "<pre>";print_r($day);echo "</pre>";
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre "pre" element represents preformatted text. Whitespace inside this element is displayed as typed.

Create the equivilent of a SELECT SUM() GROUP BY query in PHP code on variables/arrays?

I need to process a dynamic amount of incoming data (from $_POST, not a DB) that looks something like this:
ID | VALUE
10000 | 15.50
10000 | 25.00
11000 | 40.25
12000 | 20.25
11000 | 10.50
And produce an multidimensional array that sums and groups everything to end up looking like this:
array(
0 => array ('id'=>10000, 'value'=>40.50),
1 => array ('id'=>11000, 'value'=>50.75),
2 => array ('id'=>12000, 'value'=>20.25)
)
So basically the SQL statement:
SELECT id, SUM(value) FROM [table] GROUP BY id;
I'm currently trying to brute force a solution and should get there eventually, but I'm wondering if there's an 'elegant' way to do this in PHP?
There is: Use an associative array with the ID values as keys.
Start by initializing an empty array:
$totals = array ();
Then as you read values in, keep a running total for each ID in the array:
for (...) { // Read in data
if (!array_key_exists($id, $totals))
$totals[$id] = $value;
else
$totals[$id] += $value;
}
At the end of input, $totals holds the total for each ID, which you can quickly output:
echo 'ID | VALUE' . PHP_EOL;
foreach ($totals as $id => $total)
echo $id . ' | ' . $total . PHP_EOL;
Or convert to an indexed array, as in your question:
$indexed_totals = array ();
foreach ($totals as $id => $total)
$indexed_totals[] = array ($id, $total);

INSERT array into separate rows MySQL

I have a dynamic Matrix box where users can unlimited drugs, the data comes through like this:
[addindividuals] => [{"Drug":"Calpol","Strength":"100mg","Form":"Liquid","Quantity":"1"},{"Drug":"Paracetamol","Strength":"200mg","Form":"Tablet","Quantity":"16"}]
What I'm trying to achieve is to have each line inserted into a new row (MySQL) and inserts into their relevant columns like so:
Columns: | Drug | Strength | Form | Quantity
Row1 | Calpol | 100mg | Liquid | 1
Row2 |Paracetamol | 200mg | Tablet | 16
I'm guessing its using the exploded function> (I'm a novice) and then sql to insert the strings?
If you have the values as a json string collection, First you need to explode then the string then use a for each to loop through each string then use another for each to make single row. Please have a below code this may help you.
$addindividuals = '{"Drug":"Calpol","Strength":"100mg","Form":"Liquid","Quantity":"1"},{"Drug":"Paracetamol","Strength":"200mg","Form":"Tablet","Quantity":"16"}';
$exploded_array = explode('},',$addindividuals);
$final_query = "INSERT INTO `table_name` (`Drug`,`Strength`,`Form`,`Quantity`) VALUES ";
$exploded_array[0] = $exploded_array[0].'}';
foreach($exploded_array as $exploded_element)
{
$single_row = '(';
$json_decode = json_decode($exploded_element,true);
foreach($json_decode as $key => $value)
{
$single_row .= "'$value',";
}
$single_row = substr($single_row,0,-1);
$single_row .= '),';
$final_query .= $single_row;
}
$final_query = substr($final_query,0,-1);
echo $final_query;

MySql NOT IN many values from the mysql fetched result

I have 2 MySql queries which are interdependent.
My 'table1'
----------
id
----------
1
2
3
4
5
6
7
My First query
$sql1 = "SELECT * FROM table1 WHERE";// some condition which gives me id's 1,2,3
$res1=$obj->_executeQuery($sql1);
$res1=$obj->getAll($res1);
The result of this is giving me array
Array
(
[0] => Array
(
[id] => 1
..
..
)
[1] => Array
(
[id] => 2
..
..
)
[2] => Array
(
[id] => 3
..
..
)
)
I want to run another query on same 'table1', where not equal to list of ID's which i am getting from the first query.
My Second Query
$sql2 = "SELECT * FROM table1 WHERE id NOT IN (" . implode(',', $res1) . ")";
This is not showing me only one id i,e first. In above case i should get id's 4,5,6,7
Since implode will not give the desired value on multidimensional array so first you need to get the array of all id's to form one-dimensional array then use implode on the array of id's:
$id=array();
foreach ($res1 as $key=>$inner_array){
$id[]= $inner_array['id'];
}
you can use array_walk also here like this:
array_walk($res1,function($c) use (&$id) {$id[] = $c['id'];});
but i think the best one is array_map :
$id = array_map(function($i) {
return $i['id'];
}, $res1);
$sql2 = "SELECT * FROM table1 WHERE id NOT IN (" . implode(',', $id) . ")";
Note: when ever you are doing select please specify your column if you need few to select,unnecessarily selecting all will slow your sql processing.
suppose here:SELECT * FROM table1 WHERE, if you need only id then please select id only.
You have to change $res1, which is a two-dimensional array, into a one-dimensional array of IDs to be able to use implode:
$ids_from_first_query = array();
foreach($res1 as $result_row) {
$ids_from_first_query[] = $result_row['id'];
}
$ids_as_string = implode(',', $ids_from_first_query);
$sql2 = 'SELECT * FROM table1 WHERE id NOT IN(' . $ids_as_string . ')';
In the above code, $ids_as_string will look like this:
1,2,3
Thus it can be used in your MySQL query
Here you are getting two dimensional array so that's reason it is not working
while($each=mysql_fetch_array($res1))
{
$array[]=$each[id];
}
$imp=implode(",",$array);
$sql2 = "SELECT * FROM table1 WHERE id NOT IN (".$imp.")";
Try this it will works

how to select all data from mysql table where column is an array or single and my value match with one item of this array?

Please could someone help me? I want to select all values in mysql table where the column that i want to check get a value is mix with aingle or array of values....... So to be more clear I have a table to store all messages from many sender to one or many reciever....
my functions is
public static function find_messagesTo_by_user_id($mess_to=0) {
global $database;
$mess_to = $database->escape_value($mess_to);
$sql = "SELECT * FROM ".self::$table_name;
$sql .= " WHERE mess_to = '{$mess_to}'";
$sql .= " AND mess_deleted = 0";
$sql .= " ORDER BY mess_created_date DESC";
$result_array = parent::find_by_sql($sql);
return $resultrray;
}
So 'mess_to ' has array and single value .... they are only numbers Like (1, 15, 25 ,26 ,27 , array(1,25, 27) , 31, 42, .......)
Please, i break my head on it :)
I waiting for any help?
Building on #Maluchi's answer. Make sure your data looks like:
| mess_to |
+-----------------+
| ,123, |
| ,123,456,152,1, |
| ,456,567, |
| ,3, |
So surround each value in ,. then you can safely do:
WHERE `mess_to` LIKE "%,{$mess_to},%"
This ensures that $mess_to = 1 will match only the 2nd row, and not the 1st as well.
You could also denormalize your data and make a table to JOIN on.
If I'm reading it correctly, $mess_to is passed into the function and could contain either a single value or it could be passed in an array.
When matching multiple values, the SQL should be looking for a comma-separated list. The where clause needs to be IN the list rather than EQUAL to the list.
Try:
public static function find_messagesTo_by_user_id($mess_to=0) {
global $database;
$mess_to = $database->escape_value($mess_to);
$sql = "SELECT * FROM ".self::$table_name;
$sql .= " WHERE mess_to IN (" . implode(',', $mess_to) . ")";
$sql .= " AND mess_deleted = 0";
$sql .= " ORDER BY mess_created_date DESC";
$result_array = parent::find_by_sql($sql);
return $resultrray;
}
See this line in particular:
$sql .= " WHERE mess_to IN (" . implode(',', $mess_to) . ")";
Code edited with geomagas's comments! (Thank you geomagas!)
asuming your column is like this
| mess_to |
+---------+
| 1 |
| 1,2,3,4 |
| 2 |
| 3 |
you can use the LIKE operator:
$sql .= " WHERE mess_to LIKE '%{$mess_to}%'";
this will match every row where mess_to has the string value of $mess_to (your column data type should be string for this to work).

Categories