How to display multiple rows of comma separated values from mysql db - php

I need your help with display of some comma separated enteries from my database.
My main table schema looks like this
|---|----------|-----------|----------------------------|
|id | tab1 | tab2 | tab3 |
|---|----------|-----------|----------------------------|
|1 | state1 | A-North | constA1,constA2,constA3 |
|2 | state2 | B-South | constB1,constB2,constB3 |
---------------------------------------------------------
Query I'm trying to make work
$query = mysql_query("SELECT * FROM `main` WHERE `tab1` = '$tab1'")
or die(mysql_error());
while($row=mysql_fetch_array($query)){
$tab3 = explode(",", $row['tab3']);
echo $tab3."<br>";
}
What I want to display from the database
A-North B-South
---------------------
constA1 constB1
constA2 constB2
constA3 constB3
Error I'm getting when I run that query is "Array" . When I run the same code from phpMyAdmin, I get the desired rows (result).

Explode gives you the results in an array so you'll want another loop that runs through the $tab3 array printing the result. See the definition from the PHP manual:
Returns an array of strings, each of which is a substring of string
formed by splitting it on boundaries formed by the string delimiter.
For example:
for ($i = 0; $i < sizeof($tab3); $i++) {
echo $tab3[$i].'<br />';
}

explode will return array using print_r($tab3) you can view the items and access it by
echo $tab[0];
echo $tab[1];
echo $tab[2];
etc.....

explode ($separator,$string) returns an array. You need to step through the array to create the table columns.
Also, as you want the data in two columns, create these separately as two separate tables and then include those into a single table as two separate cells
Finally, redesign your database table. You'll thank us in the end

Related

Finding the differences between two rows of data, key by key

I have two rows of data - always just two rows, but there could be a maximum of around forty columns. The column names are different on a case by case basis, but here is a representative example:
id | height | width | colour | in_stock | featured | on_sale
------------------------------------------------------------
1 | 30 | 20 | black | yes | no | yes
2 | 30 | 25 | red | yes | yes | no
I want to get all of the differences between those two rows into an array so that I can log what was changed from row 1 to row 2.
I thought it array_diff() would do the job!
So I cheerfully chucked array_diff() at it thus:
//Simplified queries for the example
$sql1 = "SELECT * FROM table WHERE id = 1";
$rs1 = $conn->Execute($sql1);
$rs1 = $rs1->fields;
$sql2 = "SELECT * FROM table WHERE id = 2";
$rs2 = $conn->Execute($sql2);
$rs2 = $rs2->fields;
//Build first array
foreach($rs1 as $key => $value){
$data1[$key] = $value;
}
//Build second array
foreach($rs2 as $key => $value){
$data2[$key] = $value;
}
//Find the differences
$theDifferences = array_diff($data1, $data2);
//Loop through the differences logging the changes
foreach($theDifferences as $field => $value){
echo "Change found for ".$field."!";
}
Why that doesn't work.
This "looked like" it was working. Since many columns contain long strings, colour names, dates etc, so when one changed it was duly pushed into the differences array. The problem was (of course) that the multiple "yes" or "no" columns did not behave as I had expected. Thus the result of the code above, for the table example is:
colour, width
It is not "seeing" the featured or on_sale columns as changed because the data1 array AND the data2 array both contain no's and yes's.
I suppose I need to compare on a key by key basis? Something like the opposite of array_diff_key()? But here I am stuck.
I also considered if this could be done solely with the SQL query, which would I suppose be more efficient, but that is way beyond my SQL ability.
Thanks in advance.
I think you're very nearly there. Maybe something like this after your queries:
$theDifferences = array();
foreach($rs1 as $key => $value){
if ($rs2[$key] != $value){
$theDifferences[$key] = $value;
}
}
As for SQL, you can use an EXCEPT to get a list of rows which are different between two queries, but you'd still have to loop through the keys and look for nulls - which doesn't save you a whole lot.

Insert multiple rows into mysql database (items separated by comma)

need help...!!!
i have 2000 number of values like (3458,1356,....n)
i want to post them from html input field as $_POST['roll']; along with few other columns which has similar values like board (dhaka,dhaka,dhaka) .. i want to insert them into database with php at once not one by one..
NOTE: i know there is a way to insert multiple rows but it will be time consuming to create that query for 2000 values.. so i want to use 2000 values at once with comma..
result should be like this
+---------+-------------+
| board | roll |
+---------+-------------+
| dhaka | 3456 |
| dhaka | 4574 |
| dhaka | 6357 |
| dhaka | 2467 |
+---------+-------------+
i am using this query to post single row at a time
$board = $_POST['board'];
$roll = $_POST['roll'];
$query = "INSERT INTO `host`.`result` (`board`, `roll`) VALUES ('$board','$roll') "
At first,
you can use php explode() function to make an php array. Then you INSERT your data using loop depending on Array size.
Code Example :
$roll = array();
$board = array();
$roll = (explode(",",$_POST['roll']));
$board = (explode(",",$_POST['board']));
$arraySize = sizeof($roll);
for($i=0; $i<$arraySize ; $i++){
$query = "INSERT INTO `host`.`result` (`board`, `roll`) VALUES ($board[$i],$roll[$i]) "
}

how to use one mysql query, update data without duplicate?

id | title | text
1 | aa |
2 | aa |
3 | aa |
I have some data from json data, i am not sure how many datas have duplicate in it.
$json = '[{"a":"1","b":"bb"},{"a":"2","b":"cc"},{"a":"3","b":"bb"}]';
$array = json_decode($json);
foreach($array as $key){
UPDATE table SET text = '".$key->b."' WHERE id = '".$key->a."' and title='aa'");
}
For example, as this situation, $key->b has 2 data bb from the json data, I only want update the first one and check if bb has already in the database, then ignore update.
id | title | text
1 | aa | bb
2 | aa | cc
3 | aa | <-ignore updtae, left the data empty
I know there have an easy way, first select * from table where text != '$key->a' for check, but this will cost 2 mysql query and make one more foreach, so
how to use one mysql query, update data without duplicate?
many thanks.
If your database is MySQL, maybe you can use the ON DUPLICATE KEY UPDATE.
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
I suggest using an array to store all the values of b you have used so far and only run the UPDATE if the value didn't exist yet.
$json = '[{"a":"1","b":"bb"},{"a":"2","b":"cc"},{"a":"3","b":"bb"}]';
$usedValues = array();
$array = json_decode($json);
foreach($array as $key){
if(!isset(usedValues[$key->b])) {
mysql_query("UPDATE table SET text = '".$key->b."' WHERE id = '".$key->a."' and title='aa'");
usedValues[$key->b] = true;
}
}
EDIT: If your database already has values for text this may still produce duplicates, but you could do a SELECT DISTINCT ´text´ and populate the $usedValues array with them.

How can I make this array with data from a database?

How can I make this array with data from a database?
$array=array("a"=>"Apple","b"=>"Ball","c"=>"Cat");
I have a database table with column letter and value.
letter | value
|
a | Apple
b | Ball
c | Cat
I want "a"=>"Apple","b"=>"Ball","c"=>"Cat" to be values from the database, using for loop, how is that possible?
Many thanks for any help!
assuming you can do the connection and select
$array=array();
while ($row = mysql_fetch_assoc($result)) {
$array[$row['letter']]=$row['value'];
}
print_r($array);

PHP: using REGEX to get the tablename from a mysql query

Consider these three mysql statements:
select * from Users;
select id, title, value from Blogs;
select id, feelURL, feelTitle from Feeds where id = 1;
Now im not very good at REGEX, but i want to get the table name from the mysql query. Could someone possibly create one for me with a little explanation.
Thanks,
You can actually use MySQL as the parser and get the tablenames in your query no matter how complex your SQL syntax.
(Sorry that this is a late response to your question - I just had the same problem today and found this solution.)
Simply prefix your query with the word EXPLAIN and the results set returned to PHP will include id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra. The third column is the name of each table in your query.
For example, if your query was:
select count(*) from ey_def left join ey_rels on def_id=item_id;
Use:
explain select count(*) from ey_def left join ey_rels on def_id=item_id;
And MySQL will return this to PHP:
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | ey_def | index | NULL | PRIMARY | 4 | NULL | 87 | Using index |
| 1 | SIMPLE | ey_rels | ALL | NULL | NULL | NULL | NULL | 123 | |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
Now you can simply process the results like any other query.
Try:
preg_match('/\bfrom\b\s*(\w+)/i',$query,$matches)
This will not work if the query has more than 1 table.
Basically the regex searchs for the complete word FROM in the query and picks the following word as the table name.
A naive implementation would be this:
preg_match("/\s+from\s+`?([a-z\d_]+)`?/i", $query, $match);
echo $query . " => " . $match[1] . "\n";
This will break when you have a subquery in your SELECT field list (and probably in a few other cases). Or when your table name contains characters beside a-z, numbers and underscores.
Parsing SQL correctly isn't trivial.
For the query string you gave, the following should do:
preg_match_all('/from (\w+)/', $query, $tables);
print_r($tables[1]);
[0] => Users
[1] => Blogs
[2] => Feeds
But like pointed out in a comment already, creating a full fledged SQL parser is a non-trivial task. Don't expect this to be usable on any and all queries you throw against it.
Wish I would have seen this earlier... Like the people above me stated, it's non-trivial parsing sql statements. To pick out the table names from a sql string, it would be a better idea to get all the table names first, then find matches in the sql (providing you don't have a million tables in your database). I just so happen to have a function on hand that does just that:
/*
Takes a sql statement and attempts to get a table name from it.
This assumes a database is already specified in the connection.
[$sql]: string; SQL statement that was executed
[$conn]: resource; MySQLi connection resource
returns table name string
*/
function get_table_names($sql,$conn){
//declare variables
$table_array = array();
$table_string = "";
//get all the table names in the selected database
$sql2 = "SHOW TABLES";
$result = mysqli_query($conn, $sql2);
//display an error if something went wrong
if (!$result) {
echo "DB Error, could not list tables\n";
echo 'MySQL Error: ' . mysqli_error($conn);
exit;
}
//fetch the rows and push the table names into $table_array
while ($row = mysqli_fetch_row($result)) {
array_push($table_array, $row[0]);
}
//loop through all the tables in the database
foreach($table_array as $table){
if(strpos($sql,$table)){ //if match is found append to string
$table_string .= " $table ";
}
}
//return a string of table name matches
return $table_string;
}
Hope that helps someone...
This should do it:
(SELECT|DELETE|UPDATE|INSERT INTO) (\*|[A-Z0-9_]+)(FROM)?([A-Z0-9_, ]+)
It will works with select delete update and insert. If you use tablename1, tablename2 it will return it as a array

Categories