Joining two mysql tables and populate an array in php - php

I have two tables
First table name is "Library"
ID Name
1 A
2 B
Second table name is "Books"
BID Book_Creater Book_Name
1 Variation1 Book1
1 Variation2 Book2
1 Variation3 Book3
2 Variation1 Book4
2 Variation2 Book5
The sql is
$sql = mysql_query("select library.ID,books.Book_Creater,books.Book_name from library,books where library.ID = books.BID;
Result is
ID Book_Creater Book_name
1 Variation1 Book1
1 Variation2 Book2
1 Variation3 Book3
2 Variation1 Book4
2 Variation2 Book5
Now I would like to create an array which should look like and this is where I am stuck.
array(
[1] => array(
[Variation1] => Book1
[Variation2] => Book2
[Variation3] => Book3
)
[2] => array(
[Variation1] => Book4
[Variation2] => Book5
)
)
Any suggestion will do great.

$res = array();
//for each result row
while($row = mysql_fetch_array($sql))
{
//add a row to the multi dimensional result array
//where the first key = id and the second key = Book_Creater
$res[$row['id']][$row['Book_Creater']] = $row['Book_name'];
}
print_r($res);

Simple way is to do a join as you currently do, and push them into an array as you loop around (possibly for neatness creating a new sub array explicitly when the ID as a key doesn't already exist).
Something like this:-
<?php
$store_array = array();
$sql = mysql_query("SELECT library.ID,books.Book_Creater,books.Book_name
FROM library
INNER JOIN books
ON library.ID = books.BID");
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result))
{
if (!array_key_exists($row['ID'], $store_array))
{
$store_array[$row['ID']] = array();
}
$store_array[$row['ID']][$row['Book_Creater']] = $row['Book_name']
}
print_r($store_array);
?>
You could also shuffle some effort onto the database and bring things back concatenated together. Then just split the results to put into the array:-
<?php
$store_array = array();
$sql = mysql_query("SELECT library.ID, GROUP_CONCAT(CONCAT_WS('#~#', books.Book_Creater,books.Book_name)) AS details
FROM library
INNER JOIN books
ON library.ID = books.BID
GROUP BY library.ID");
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result))
{
$store_array[$row['ID']] = array();
$details = explode(',', $row['details']);
foreach($details as $detail)
{
$detail_line = explode('#~#', $row['detail']);
$store_array[$row['ID']][$detail_line[0]] = $detail_line[1];
}
}
print_r($store_array);
?>
Note that if you are doing this with real data you probably want to chose delimiters which are not going to appear in your data, and also that by default GROUP_CONCAT has a fairly limited max length.
Note also I have used mysql_* functions as that is what you seem to be using, but these are deprecated and probably shouldn't be used now.

Related

get nested json response

I have table store_profile like this
id Storename Storetype address
1 Samsung Store Electronics Delhi
2 Levi Clothing Mumbai
3 Soni Electronics Bangalore
and second table Offers
id Store_id offer price
1 Samsung Store flat 30% off 20000
2 Levi Exchange 5000
3 Samsung Store Exchange offer 40000
I want to get all the store details from store_profile for particular type,say Electronics and for each store their offers in single row,not repeated as I am getting from this syntax in json mysql query is :-
SELECT * , Offers.Store_id
FROM Store_profile INNER JOIN
Offers
ON Store_profile.Storename = Offers.Store_id AND
Store_profile.Storetype like '%Electronics%'
Here is my php code
$sql ="SELECT * , Offers.Store_id FROM Store_profile INNER JOIN Offers ON Store_profile.Storename = Offers.Store_id AND Store_profile.Storetype like '%Electronics%' LIMIT 0 , 300 ";
$r = mysqli_query($con,$sql);
$result = array();
while($row = mysqli_fetch_array($r)){
array_push($result,array(
'Store_Name'=>$row['Storename'],
'Store_address'=>$row['address'],
'Offer_Title'=>$row['offer'],
'MRP_Price'=>$row['price'],
)
);
}
echo json_encode(array('result'=>$result));
mysqli_close($con);
... i want to get json like this result["Storename"-Samsung Store,Store_address - Delhi,Offer[Offer_Title-Flat 30% Off,MRP_Price20000,Offer_Title-Exchange offer,MRP_Price40000 ]]
Change your while() loop and the subsequent json_encode() function call in the following way,
$result = array();
while($row = mysqli_fetch_array($r)){
if(!isset($result[$row['Store_id']])){
$result[$row['Store_id']] = array('Store_Name'=>$row['Storename'], 'Store_address'=>$row['address']);
}
$result[$row['Store_id']]['offer'][] = array('Offer_Title'=>$row['offer'],'MRP_Price'=>$row['price']);
}
echo json_encode(array('result' => array_values($result)));
Update:
From your comment,
... i have one store in store_profile but this store doesnt have any offer in Offers table. I am not getting this store's data in my json
You have to use LEFT JOIN to include all the matched rows from the Store_profile table in the result set. Furthermore, you need to use WHERE instead of AND after the joining condition. So your query should be like this:
SELECT * , Offers.Store_id
FROM Store_profile
LEFT JOIN Offers
ON Store_profile.Storename = Offers.Store_id
WHERE Store_profile.Storetype LIKE '%Electronics%'
LIMIT 0 , 300
Subsequently, change your while() loop and json_encode() function call in the following way,
$result = array();
while($row = mysqli_fetch_array($r)){
if(!isset($result[$row['Storename']])){
$result[$row['Storename']] = array('Store_Name'=>$row['Storename'], 'Store_address'=>$row['address']);
}
if(isset($row['offer']) && isset($row['price'])){
$result[$row['Storename']]['offer'][] = array('Offer_Title'=>$row['offer'],'MRP_Price'=>$row['price']);
}else{
$result[$row['Storename']]['offer'] = array();
}
}
echo json_encode(array('result' => array_values($result)));

grouping datas with same group

I'm trying to achieve to group Data by a column named 'groups'. I've been looking this post here Categorizing mysql data into seperate html tables?
This is also applicable in my case but the same groups get separated
This is what it looked like
_____________________________________
|_____________Group ZXY_______________|
| Month | Bet | Win |Payout|
|_______________|_______|______|______|
|Name|Group|Desc| | | |
|_______________|_______|______|______|
|Name|Group|Desc| | | |
|_______________|_______|______|______|
|_____Total_____|_______|______|______|
_____________________________________
|_____________Group ZXY_______________|
| Month | Bet | Win |Payout|
|_______________|_______|______|______|
|Name|Group|Desc| | | |
|_______________|_______|______|______|
|Name|Group|Desc| | | |
|_______________|_______|______|______|
|_____Total_____|_______|______|______|
As you can see the data returned are having the same group but got separated. Must be only using 1 table in this case
Summary of my idea
Group loop
add
<table><th>..</th></table>
tags inside the variable
Data fetch loop
add
<tr><td>..</td></tr>
tags inside the variable
Here's the code
$sql='SELECT DISTINCT `groups` FROM `kiosk_data` WHERE `groups` IS NOT NULL ORDER BY `groups` ASC';
$grpData='';
$grpHr[]=array();
//this is the code I used to fill im th contents of the dropdown box
$result = $conn->query($sql);
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
if(!empty($row['groups']))
{
$selected = (isset($_GET['grp']) && $_GET['grp']==$row['groups'])?'selected="selected"':'';
$grpData.='<option value="'.$row['groups'].'"'.$selected.'>'.$row['groups'].'</option>';
$grpHr[]=$row['groups'];//took this opportunity to store the values of groups in grpHr[] Array
}
}
$sql = "SELECT COALESCE(kd.`kiosk_name`,'Total') AS 'Kiosk',
FORMAT(SUM(`casino_bets`),2) AS 'CBTotal', FORMAT(SUM(`bet_win`),2) AS 'BWTotal'
,FORMAT((`casino_bets`-`bet_win`)/`casino_bets`*100,2) AS 'Payout', groups FROM
`kiosk_data` kd LEFT JOIN `kiosk_status` ks ON kd.`kiosk_id`=ks.`kiosk_id` WHERE
`kiosk_name` IS NOT NULL AND `casino_bets` IS NOT NULL AND `bet_win` IS NOT NULL";
$result = $conn->prepare($sql);
$result ->execute();
foreach ($grpHr as $key => $value) {//iterate til the last group name
$key = $row['groups'];//I think I need to do this before entering the fetch loop
echo '<table><tr><td colspan="6">'.$row['groups'].'</td></tr><tr><th colspan="3">'.date("m",strtotime($row['date'])).'Month</th><th>Bet</th><th>Bet-Win</th><th>Payout %</th></tr>';
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
echo '<tr><td>'.$row['Kiosk'].'</td><td>'.$row['groups'].'</td><td>'.$row['city'].'</td><td>'.$row['CBTotal'].'</td><td>'.$row['BWTotal'].'</td><td>'.$row['Payout'].'</td></tr>';
}
}
Any other possible workaround for something better aside from my idea?
Assuming that your second query retrieves the needed data, please try the following version of your PHP code:
$sql='SELECT DISTINCT `groups` FROM `kiosk_data` WHERE `groups` IS NOT NULL ORDER BY `groups` ASC';
$grpData='';
$grpHr[]=array();
//this is the code I used to fill im th contents of the dropdown box
$result = $conn->query($sql);
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
if(!empty($row['groups']))
{
$selected = (isset($_GET['grp']) && $_GET['grp']==$row['groups'])?'selected="selected"':'';
$grpData.='<option value="'.$row['groups'].'"'.$selected.'>'.$row['groups'].'</option>';
$grpHr[]=$row['groups'];//took this opportunity to store the values of groups in grpHr[] Array
}
}
$sql = "SELECT COALESCE(kd.`kiosk_name`,'Total') AS 'Kiosk',
FORMAT(SUM(`casino_bets`),2) AS 'CBTotal', FORMAT(SUM(`bet_win`),2) AS 'BWTotal'
,FORMAT((`casino_bets`-`bet_win`)/`casino_bets`*100,2) AS 'Payout', groups FROM
`kiosk_data` kd LEFT JOIN `kiosk_status` ks ON kd.`kiosk_id`=ks.`kiosk_id` WHERE
`kiosk_name` IS NOT NULL AND `casino_bets` IS NOT NULL AND `bet_win` IS NOT NULL";
$result = $conn->prepare($sql);
$result ->execute();
$grpsArr = array();
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
if( ! isset($grpsArr[$row['groups']])) {
$grpsArr[$row['groups']] = array();
}
$grpsArr[$row['groups']][] = $row;
}
foreach ($grpsArr as $grpName => $grpRowArray) {
echo '<table><tr><th colspan="6">'.$grpName.'</td></tr><tr><th colspan="3">'
.date("m",strtotime($row['date']))
.' Month</th><th>Bet</th><th>Bet-Win</th><th>Payout %</th></tr>';
foreach($grpRowArray as $grpRow) {
echo '<tr><td>'.$grpRow['Kiosk'].'</td><td>'.$grpRow['groups'].'</td><td>'.$grpRow['city'].'</td><td>'.$grpRow['CBTotal'].'</td><td>'.$grpRow['BWTotal'].'</td><td>'.$grpRow['Payout'].'</td></tr>';
}
echo '</table>';
}
What has been changed are the while / foreach loops. Below please find the explanation.
while loop
$grpsArr = array();
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
if( ! isset($grpsArr[$row['groups']])) {
$grpsArr[$row['groups']] = array();
}
$grpsArr[$row['groups']][] = $row;
}
This loop iterates through all of the rows returned by your last query, putting the data into $grpsArr nested array. The section :
if( ! isset($grpsArr[$row['groups']])) {
$grpsArr[$row['groups']] = array();
}
checks whether there has already been at least one row from the $row['groups'] group throughout the iteration - if there was no such row till now, sub array is created for $row['groups'] group name;
The line:
$grpsArr[$row['groups']][] = $row;
adds current iteration row to the subarray of the group indicated in $row['groups'].
After fetching the last record from the recordset, the $grpsArr array should look like:
grpsArr = array {
"group_1" => array {
array {
"Kiosk" => "KioskVal_1",
"groups" => "group_1",
"city" => "city_1",
"CBTotal" => 123.45
"BWTotal" => ...
"Payout" => ...
} ,
( ......... ) ,
array {
"Kiosk" => "KioskVal_31",
"groups" => "group_1",
"city" => "city_11",
"CBTotal" => 123.45
"BWTotal" => ...
"Payout" => ...
}
}
( .................... ),
"group_m" => array {
array {
"Kiosk" => "KioskVal_m",
"groups" => "group_m",
"city" => "city_m",
"CBTotal" => 123.45
"BWTotal" => ...
"Payout" => ...
} ,
( .................... ) ,
array {
"Kiosk" => "KioskVal_m2",
"groups" => "group_2",
"city" => "city_mm",
"CBTotal" => 123.45
"BWTotal" => ...
"Payout" => ...
}
}
}
foreach loop
foreach ($grpsArr as $grpName => $grpRowArray) {
echo '<table><tr><th colspan="6">'.$grpName.'</td></tr><tr><th colspan="3">'
.date("m",strtotime($row['date']))
.' Month</th><th>Bet</th><th>Bet-Win</th><th>Payout %</th></tr>';
foreach($grpRowArray as $grpRow) {
echo '<tr><td>'.$grpRow['Kiosk'].'</td><td>'.$grpRow['groups'].'</td><td>'.$grpRow['city'].'</td><td>'.$grpRow['CBTotal'].'</td><td>'.$grpRow['BWTotal'].'</td><td>'.$grpRow['Payout'].'</td></tr>';
}
echo '</table>';
}
The main loop foreach ($grpsArr as $grpName => $grpRowArray) iterates through the first level of $grpsArr table, getting the group name of currently processed group and then builds HTML table start tag with header row for this specific group.
Internal loop foreach($grpRowArray as $grpRow) iterates over the array containing rows that belong to the the currently processed group and builds HTML table row from the obtained data.
There is one problem: you used in your code .date("m",strtotime($row['date'])). for writing the proper date/time for the group. However there is no date field in the results of the last query - nevertheless I've put it also in my code.
This approach should give you one HTML table for each of the groups.
I hope it helps you some way.

Is using PHP to loop a mySQL query efficient?

I have a HTML table full of check-boxes on page 1 with the name attribute set like this:
input type="checkbox" name="A_1"
input type="checkbox" name="B_2"
On the following page, I loop through my $_POST array in PHP with explode to make an array like this:
Array ( [A_1] => on [A_2] => on [B_2] => on [B_5] => on [C_5] => on [submit] => Submit )
Into two arrays:
row_Array = Array ( [0] => 1 [1] => 2 [2] => 2 [3] => 5 [4] => 5 )
column_Array = Array ( [0] => A [1] => A [2] => B [3] => B [4] => C )
This is my SQL query:
for($i=0; $i < count($column_array); $i++) {
$sql = "SELECT {$column_array[$i]} FROM table WHERE num IN ({$row_array[$i]})";
$result = mysqli_query($connection, $sql);
while ($data = mysqli_fetch_assoc($result)) {
$result_array[] = $data[$column_array[$i]];
}
}
Here is an example of my SQL table:
A B C
1 cat cot cet
2 rat rot ret
3 hat hot het
4 lat lot let
5 bat bot bet
The individual SQL queries from my loop look like this and return the correct values:
SELECT A FROM table WHERE num IN (1) returns cat
SELECT A FROM table WHERE num IN (2) returns rat
SELECT B FROM table WHERE num IN (2) returns rot
SELECT B FROM table WHERE num IN (5) returns bot
SELECT C FROM table WHERE num IN (5) returns bet
I am quite new to sql and php. This works but it seems like a terrible way to do this. Any advice or help would be greatly appreciated.
I believe it's a better practice to run a single query and loop through the data returned rather than looping and then running multiple queries.
However, depending on your data structure and application layout, UI, etc, that may not be possible.
I would aim for something like SELECT A,B,C,num FROM table WHERE num IN (1,2,5)
then maybe
foreach($result as $r){
$data[$r['num']] = $r;
}
Let's try just running one query and loop trough it. It's pretty much #Andy Gee 's answer expressed in code.
$cols = implode(',', array_unique($column_array));
$rows = implode(',', array_unique($row_array));
$sql = "SELECT {$cols} FROM table WHERE num IN ({$rows})";
$result = mysqli_query($connection, $sql);
while ($data = mysqli_fetch_assoc($result)) {
//Do your stuff here
}
Something like, it's realy bad idea but..:
$columns = implode(', ', $column_array);
$num_values = implode(', ', $row_array);
$sql = "SELECT {$columns}, num FROM table WHERE num IN ({$num_values})";
$result = mysqli_query($connection, $sql);
while ($data = mysqli_fetch_assoc($result)) {
$result_array[] = $data[$column_array[$i]];
}
Other way is to build one long Query with UNION
SELECT A as value, num FROM table WHERE num = 1
UNION
SELECT A as value, num FROM table WHERE num = 2
UNION
SELECT B as value, num FROM table WHERE num = 2
UNION
SELECT B as value, num FROM table WHERE num = 5
UNION
SELECT C as value, num FROM table WHERE num = 5
returns:
array(
array("num" => 1, "value" => 'cat'),
array("num" => 1, "value" => 'rat'),
...
);

How get all two array values using select query at once

I want to get Name and corresponding Score at the latest time. So I tried:
$queryObj = mysql_query("SELECT `Name`,`Score` from `Table`.`Score` where `Date` = ( SELECT max(`Date`) from `Table`.`Score`) and `Name`<>'' ");
then get value from it by:
while( $obj = mysql_fetch_object( $queryObj ) ) {
$data = array();
$data['Name'] = $obj->Name;
$data['Score'] = $obj->Score;
$searches[] = $data;
}
But when I print :
print_r(array_values($searches));
the first value is missing in the array, so that won't be the right way.
I also tried:
$row = mysql_fetch_assoc($queryObj);
for ($i = 0; $i <3; $i++)
print( $row['Name'][$i]." Score: ".$row['Score'][$i]."<br />\n");
But it won't give me the right results also. How do I get the value from that query? (the query is correct, I tested it). Any body has suggestion ?
Edit: I add my sample data here:
Name Score Date
abc 3 2013-08-29 10:11:47
abc 2 2013-08-29 09:39:23
abc 1 2013-08-28 10:22:28
jane 2 2013-08-29 09:39:23
2013-08-29 10:08:36
jane 1 2013-08-29 10:11:47
tarzan 1 2013-08-29 10:11:47
Note: Yes, there is some blank values.
My expected result would be:
abc score 3
jane score 1
tarzan score 1
Ok, so after you have updated your question and provided what you expect, your query should look like this:
SELECT t1.Name, t1.Score
FROM Table.Score t1
INNER JOIN
(
SELECT max(Date) MaxDate, Name, Score
FROM Table.Score
WHERE Name <> ''
GROUP BY Name
) t2
ON t1.Name = t2.Name AND t1.Date = t2.MaxDate
This will give you pairs of Name and Score for each Name with Score based on his latest Date (1 row per Name).
So replace your original query with mine in this line:
$queryObj = mysql_query(" ... ");
Then:
$rows = array();
while($row = mysql_fetch_assoc($queryObj)) {
$rows[$row['Name']] = $row['Score'];
}
And you can nicely foreach it in the exact way you wanted in your last comment:
foreach($rows as $name => $score) {
echo $name . ' - ' . $score . "\n";
}

Why returns the first element of an array only?

$count =0;
$result1 = mysql_query("SELECT fwid FROM sbsw WHERE fword = '".$searchText."'");
while ($result2= mysql_fetch_array($result1))
{
$result3 = mysql_query("SELECT fsyn FROM wrsyn WHERE fwid = '".$result2[$count]."'");
$result4= mysql_fetch_array($result3);
print $result4[$count].'<br>';
$count++;
}
mysql_free_result($result1);
mysql_free_result($result3);
Let's have a look at how mysql_fetch_array works - for example if you have table structure like
id | name | surname | role
1 John Smith user
2 Peter Qeep user
3 Mark Ziii admin
When you execute a query SELECT * FROM table and then loop $result = mysql_fetch_array($query), $result will always be an array(4) containing
[0] => id,
[1] => name,
[2] => surname,
[3] => role
Therefore, when you execute the query $result3 = mysql_query("SELECT fsyn FROM wrsyn WHERE fwid = '".$result2[$count]."'");, in the first iteration, $count will be 0 which is the key for the result returned by the previous query, however in any further iteration it will increase and that will lead to an undefined key. This means that you have to stop using the variable $count and just use $result2[0] instead.
Also, way better approach to this would be using MySQL JOIN, in your example it would be SELECT w.fsyn FROM sbsw s JOIN wrsyn w ON s.fwid = w.fwid WHERE s.fword = "'.$searchText.'";
Please, use reasonable variable names and indent properly. You're getting one column from each row as you're only printing out once for each iteration over your rows.
Basically: For each row, print the value of a column.
The $count-variable decided which column, but it obviously didn't make sense at it counts the row you're at.
Something like this should do it: (not tested)
$result1 = mysql_query("SELECT fwid FROM sbsw WHERE fword = '".$searchText."'");
while ($result2= mysql_fetch_array($result1))
{
$result3 = mysql_query("SELECT fsyn FROM wrsyn WHERE fwid = '".$result2['fwid']."'");
$result4= mysql_fetch_row($result3);
for($x = 0; $x < count($result4); $x++){
print $result4[$x].'<br>';
}
}
mysql_free_result($result1);
mysql_free_result($result3);
Oh and I changed fetch_array to fetch_row in the inner loop to ease iteration.

Categories