I am looking for some help to build a generic PHP function that will take in the output of SQL query
SELECT DISTINCT categoryID, StatusID, COUNT( * ) FROM tableA GROUP BY categoryID
Sample result:
categoryID StatusID COUNT( * )
CategoryB On Hold 1
CategoryA On Hold 4
CategoryC On Hold 3
CategoryB Draft 1
There can be any number of CategoryIDs and Statuses in the database...
and return a TABULAR table format:
My desired outcome goes something like this:
Status Summary Table by Category:
---------------------------------------------------------
| CategoryA | CategoryB | CategoryC | ... | TOTAL
Completed | 0 | 1 | 0 | ... | 1
On Hold | 4 | 0 | 3 | ... | 7
Draft | 0 | 1 | 1 | ... | 2
---------------------------------------------------------
TOTAL: | 4 | 2 | 4 | ... | 10
I figure it out! -- I am hoping this helps someone else in the future..
It is not pretty code, but it works and it is pretty genetic so it can be used as needed..
Who it is called:
$sql="SELECT DISTINCT categoryID, statusID, COUNT( * ) as Count1 FROM entries GROUP BY categoryID" ;
$results = mysql_query($sql, $con);
// Now that we have both Status and Category, lets place the counts in the right cells:
echo displayTabularSum ($myarray,"status","category",1) ;
Now the functions I used:
function displayTabularSum($myarray, $table1,$table2,$includeTotals)
{
// First get all data from $table1 into an array
$sql = "SELECT * FROM $table1 WHERE 1";
$results= mysql_query($sql);
$statusCodes= getsqlresultintoarray ($results) ;
// Second: get all data from $table2 into an array
$sql = "SELECT * FROM $table2 WHERE 1";
$results= mysql_query($sql);
$categoryCodes= getsqlresultintoarray ($results) ;
// Now create the results table with appropriate values in columns
$statusTable=array();
$out = '';
$first = true;
$cT=array();
for ($x=0; $x';
for ($y=0; $y'.$categoryCodes[$y][1].'';
}
if ($includeTotals) $out.= 'Total';
$out.= '';
$first = false;
}
$out .="";
$out .="".$statusCodes[$x][1]."";
$rT=0;
for ($y=0; $y";
$c1=searchForId($categoryCodes[$y][0], $myarray, "categoryID");
$c2=searchForId($statusCodes[$x][0], $myarray, "statusID");
$count1=0;
$same=($c1==$c2);
If ( $same ) {
If ($c1==99999 OR $c2==99999) {
// do nothing... These are NULLs
} else {
$count1=$count1+$myarray[$c1]['Count1'];
}
}
$out .= $count1;
$rT=$count1+$rT;
$cT[$y]=$cT[$y]+$count1; // Collecting column Totals
$out .="";
}
if ($includeTotals) $out.= ''.$rT.''; // display rowTotal
$out .="";
}
if ($includeTotals) { // Display the column Total before closing table.
$cT1=0;
$out .="";
$out.= 'Total:';
for ($x=0; $x'.$cT[$x].'';
$cT1=$cT1+$cT[$x];
}
$out.= ''.$cT1.'';
$out .="";
}
$out .="";
return $out;
}
Function getresultsintoarray1 ($results)
{ // Function to get all results from a SQL QUery into an Array.
$num_rows = mysql_num_rows($results);
$myarray=array();
if ($num_rows>0) {
while($row = mysql_fetch_assoc($results))
{
$myarray[] = $row;
}
}else
{
echo " No data found on database... " ;
unset($myarray);
$myarray=array();
}
return $myarray;
}
function getsqlresultintoarray ($get) // YES
{
$num_rows = mysql_num_rows($get);
$returnArray=array();
$i=0;
while($row1 = mysql_fetch_array($get)) {
$returnArray[$i][0]=$row1[0]; // This is the ID
$returnArray[$i][1]=$row1[1]; // This is the name
$i++;
}
return $returnArray;
}
function searchForId($id, $array, $field)
{
If (count($array)>0) {
foreach ($array as $key => $val) {
if ($val[$field] === $id) {
return $key;
}
}
}
return 99999;
}
If anyone has ideas as to how to improve, I would appreciate it!
Related
I have a MySQL table with multiple columns, from which I need to select all of them of each record, and to create a specific $key=>$value from it.
for example
TABLE
ID | group_cat | group_sec | group_name | enabled | sent
-------------------------------------------------------------------------------------
1 | C | sct_a | Project_A | 1 | no
2 | C | sct_b | Project_B | 1 | no
3 | P | sct_c | Moderators | 1 | no
4 | C | sct_d | Ambassad | 1 | no
5 | P | sct_e | PMP | 0 | no
The MySQL query I need is "SELECT * FROM groups WHERE sent = 'no' "
By PHP is
PHP Code
$query = "SELECT * FROM `groups` WHERE `sent`= 'no' ";
$sth = $sql->prepare($query);
$sth->execute();
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
foreach($row as $key => $value) { $$key = $value; }
...
...
...
}
Here my question:
I need that the $key is from the column 'group_sec' and the related $value is from the column 'group_name'. So that the couple $$key=>$value can return this result (for instance)
echo $sec_b;
returns: Project_B
Could you help me to get this done please?
Thank you in advance
This will do the job for you:
${$row['group_sec']} = $row['group_name'];
echo $sct_b;
Output:
Project_B
You would use this in your while loop (the foreach can probably be deleted):
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
${$row['group_sec']} = $row['group_name'];
...
// do something with $sct_b
...
}
Alternatively, if your column names might change, but the positions will stay the same, you can use
while($row = $sth->fetch(PDO::FETCH_NUM)) {
${$row[2]} = $row[3];
...
// do something with $sct_b
...
}
You can build an array based on key and value you prefer using $row['group_sec'] for key and $row['group_name'] eg:
$query = "SELECT * FROM `groups` WHERE `sent`= 'no' ";
$sth = $sql->prepare($query);
$sth->execute();
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
$myArray[$row['group_sec']] = $row['group_name'];
}
and you can see the result
foreach($myArray as $key => $value){
echo $key . ' - ' . $value . '<br>';
}
$sql = "SELECT * FROM groups WHERE sent= 'no'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
$list=[];
while($row = $result->fetch_assoc()) {
$list{$row['group_sec']} = $row['group_name'];
}
}
I have this table:
| id | related_id |
| 1 | 100 |
| 1 | 200 |
| 1 | 300 |
| 2 | 400 |
| 2 | 500 |
| 2 | 600 |
I need to retrieve serialized data as:
a:3:{i:1;s:3:"100";i:2;s:3:"200";i:3;s:3:"300";}
Query
SELECT id, related_id from mytable where id = 1;
I'm trying to get this using 'while'
$result = $link->query($query);
$item = array();
while($f = $result->fetch_assoc()){
$id = $f['id'];
if ($id == $f['id']){
$item[] = $f['related_id'];
}
print serialize($item);
break; // for test
}
SOLUTION that works for me (provided by Erwin - Thanks!)
$item = array();
while($f = $result->fetch_assoc()) {
$id = $f['id'];
if (!array_key_exists($id, $item)) {
$item[$id] = [1 => $f['related_id']];
} else {
$item[$id][] = $f['related_id'];
}
}
foreach ($item as $value) {
print serialize($value) . PHP_EOL;
}
Collect first each related_id and store to id array with your while loop. Then print each using foreach.
$item = array();
while($f = $result->fetch_assoc()) {
$id = $f['id'];
if (!array_key_exists($id, $item)) { // create id array if not exist
$item[$id] = [1 => $f['related_id']]; // To start with index 1
} else {
$item[$id][] = $f['related_id']; // Push each new related_id
}
}
foreach ($item as $value) {
print serialize($value); // Print each serialized
echo '<br>'; // New line
}
What you are trying to do is something like this:
$result = $link->query($query);
$items = array();
while($f = $result->fetch_assoc()){
$id = $f['id'];
if(!isset($items[$id])) {
$items[$id] = array();
}
$items[$id][] = $f['related_id'];
}
foreach($items as $item) {
print serialize($item);
}
For your serialized string, you have to work with an array with related_id in the second layer. The first layer is to save all related_id in an array with the same id.
You have 6 rows, 3 have id 1 and 3 have id 2. You are specifying that you want to use these ids as array keys so you will end up with 2 arrays, each holding 3 values.
If you want each row in its own array you do this:
while($f = $result->fetch_assoc()){
$item[] = array($f['id'] => $f['related_id']);
}
I have been trying to fureout how to create a dynamic multi dimensional array.
The reason for this is that I want to create a dropdown menu that will be created dynamically from the mysql
Sample database
|id|menu_name|menu_parent_id|
|1 |top menu1| 0 |
|2 |top menu2| 0 |
|3 |top menu3| 0 |
|4 |top menu4| 0 |
|5 |sub menu | 2 |
|6 |sub menu | 2 |
|7 |sub menu | 5 |
|8 |sub menu | 6 |
|9 |top menu | 0 |
I thought of starting from getting the menu with no parent then put it on an array
$parentIDs[0]=0;
$tempParentIDs = array();
$childIDs = array();
$menus = array();
$rows = 0;
$rows=0;
foreach($parentIDs AS $value){
$sql = mysql_query("SELECT * FROM service WHERE service_parent_id=$value");
while($temp = mysql_fetch_array($sql)){
//$tempParentIDs[] = $temp['service_id'];
//check if parent have child
$sql2 = mysql_query("SELECT * FROM service WHERE service_parent_id=$temp[service_id]") or die(mysql_error());
$rows = mysql_num_rows($sql2);
if($rows >= 1){
//This means there is a child
while($temp2 = mysql_fetch_array($sql2)){
$childIDs[] = $temp2['service_id'];
}
$tempParentIDs[$temp['service_id']] = $childIDs;
unset($childIDs);
} else {
//This means there is no child
}
}
}
echo "<pre>";
print_r($tempParentIDs);
echo "</pre>";
but after then I'm stuck.
I think you are looking for this:
$parentIDs[0]=0;
$tempParentIDs = array();
$childIDs = array();
$menus = array();
$rows = 0;
$multiDimensionalArray = NULL; //here I made change - vijay
$rows=0;
foreach($parentIDs AS $value){
$sql = mysql_query("SELECT * FROM service WHERE service_parent_id=$value");
while($temp = mysql_fetch_array($sql)){
$tempParentIDs = $temp['service_id']; //here I made change - vijay
//check if parent have child
$sql2 = mysql_query("SELECT * FROM service WHERE service_parent_id=$temp[service_id]") or die(mysql_error());
$rows = mysql_num_rows($sql2);
if($rows >= 1){
//This means there is a child
while($temp2 = mysql_fetch_array($sql2)){
$multiDimensionalArray[$tempParentIDs][] = $temp2['service_id']; //here I made change - vijay
}
// $tempParentIDs[$temp['service_id']] = $childIDs; //here I made change - vijay
// unset($childIDs); //here I made change - vijay
} else {
//This means there is no child
}
}
}
echo "<pre>";
print_r($multiDimensionalArray); //here I made change - vijay
echo "</pre>";
You should store array in php like this way :
This will maybe work for you
$next = 0;
$level = 0;
$sql = mysql_query("SELECT * FROM service WHERE service_parent_id=$next");
$temps = array();
while($temp = mysql_fetch_array($sql))
{
$temps[] = $temp;
}
foreach($temps as $temp)
{
echo $temp['service_id'];
}
this is MySQL table structure:
TABLE: products
|----------------------------------------------|
| id | product_ids |
| 1 | 51 |
| 2 | 616,2,38 |
| 3 | (NULL) |
| 4 | 426,605,604 |
|----------------------------------------------|
What im looking is a way for the code to check if the id 605 exists in product_ids row, and if it does to replace for another ID:
any idea how can i accomplish this?
I was thinking of a sql QUERY...
$sql = "SELECT * FROM products";
$r1=$con->execute_query($sql);
while ($row1 = mysql_fetch_array($r1, MYSQL_ASSOC)) {
if($row1['product_ids']) {
$data = preg_split('/,/', $row1['product_ids']);
if(is_array($data)) {
foreach($data as $key => $value) {
if($value == 605) {
echo $value;
}
}
}
}
}
Check it out on CodePad
This is the best http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set for denormalization problem
while ($row1 = mysql_fetch_array($r1, MYSQL_ASSOC)) {
if($row1['product_ids']){
$val_changed = false;
$prod_ids = $row1['product_ids'];
$ids = explode(',', $prod_ids);
for($i = 0; $i < count($ids); $i++) {
if($ids[$i] === '605') {
$ids[$i] = $new_id;
$val_changed = true;
}
}
if($val_changed) {
$prod_ids = implode(',', $ids);
//update db with new value $prod_ids
}
}
}
To get only records that have the id you're looking for, and use preg_replace to change the value, and update the table with the new value
$new_id = '999';
$new_val = preg_replace('/,605,/', $new_id, $row1['product_ids']);
Query with Regex (Fancy!):
SELECT * FROM products WHERE product_ids REGEXP '^[^0-9]605[^0-9]$';
Script to modify data:
while( $row1 = mysql_fetch_array( $r1, MYSQL_ASSOC ) )
{
$product_ids = explode( ',', $row1['product_ids'] );
if( ( $key = array_search( '605', $product_ids ) ) !== FALSE )
{
$product_ids[$key] = $new_id_number;
$product_ids = implode( ',', $product_ids );
// Enter Code to Update Table Here
}
}
To find out if it contains '605':
SELECT id, product_ids FROM products
where product_ids REGEXP '^.*[^\d]605(?!\d).*$'
Comment: this is, by the way, a very good example why we shouldn't use multiple values in the same field!
Now once you have it - you can do whatever you want, you can play with it:
$new_product_ids = preg_replace('/^(.*[^\d])(605)(?!\d)(.*)$/','${1}new_id${3}',$row1['product_ids']);
and update the row:
update products set product_ids = '$new_product_ids' where id = $id
I have a database like this:
+----+---------------------+
| id | tags |
+----+---------------------+
| 1 | test1, test2, test3 |
| 2 | test1, test2, test3 |
| 3 | test1, test2, test3 |
| 4 | test1, test2, test3 |
| 5 | buh1, buh2, buh3 |
+----+---------------------+
Now i want to display the most popular tags from this database. I have a function, and it works with a array like this:
$tag_array = array(
'test1, test2 test, test3',
'test2, test4, test2',
'buh, buh2, buh3' );
The function:
function popularTags($tag_array) {
$p = array();
foreach($tag_array as $tags) {
$tags_arr = array_map('trim', explode(',', $tags));
foreach($tags_arr as $tag) {
$p[$tag] = array_key_exists($tag, $p) ? $p[$tag]+1 : 1;
}
}
arsort($p);
return $p;
}
This is how to display the most popular tags:
foreach(popularTags($tag_array) as $tag=>$num)
{
echo $tag, " (", $num, ")<br />";
}
This works so far, with a normal array.
Now, i want to get the tags from the Database, so i extract the values from the database and run the function like this:
$result = mysql_query("select * from DB ORDER BY date DESC");
while($row = mysql_fetch_array($result)){
$tag_array = $row["$tags"];
foreach(popularTags($tag_array) as $tag=>$num)
{
echo $tag, " (", $num, ")<br />";
}
}
This give me an error though:
Warning: Invalid argument supplied for foreach()
So my question is how to show the most popular tags from the database with this function?
Thanks
My suggestion is that you normalize your database. Then a query like this becomes trivial, as well as much better performing.
select TagID, count(*)
from EntityTag
group by TagID
order by count(*) descending
limit 5
mysql_fetch_array returns all the rows. So do this:
$rows = mysql_fetch_array($result);
foreach($rows as $row) {
$tag_array = $row["tags"]; // note removing the $
foreach(...) {
}
}
This one works for me:
$result = mysql_query("select tags from DATABASE LIMIT 20");
$tags = array();
while ($row = mysql_fetch_array($result)) {
$row_tag_array = split(",", $row[0]);
foreach ($row_tag_array as $newtag) {
asort($row_tag_array);
if (array_key_exists($newtag, $tags)) {
if ($tags[$newtag] < 200) {
$tags[$newtag] = $tags[$newtag] + 20;
}
}
else {
$tags[$newtag] = 100;
}
}
}
foreach ($tags as $tag => $size) {
echo "<a style=\"font-size: $size%;\" href=\"?t=$tag\">$tag</a> ";
}
Thank you for your help though