PHP mysql select to array and check if value exist - php

I have this MySQL table:
Where I want to get count of each platform (windows, linux, mac, unknown).
Notice that in table is no mac or unknown data, there for num will be 0
Conditions:
order must be like in wanted output
check if plaform is in table, if not add zero to output
Question: How to sort in query to have order like in wanted output, and add zero if no platform in table?
Wanted output:
array (
'0' => array('name' => 'windows', 'num' => 3),
'1' => array('name' => 'linux', 'num' => 3),
'2' => array('name' => 'mac', 'num' => 0),
'3' => array('name' => 'unknown', 'num' => 0)
);
My try:
PHP:
function get_platforms() {
$query = "
SELECT platform, COUNT(platform) AS num
FROM stats
GROUP BY platform
ORDER BY platform ASC
";
$select = mysqli_query($this->c, $query);
while ($row = mysqli_fetch_array($select)) {
$data[] = array(
'name' => $row['platform'],
'num' => $row['num']
);
}
return $data;
}
Current outpup:
array (
'0' => array ('name' => 'linux', 'num' => 3)
'1' => array ('name' => 'windows', 'num' => 3)
);

Because you don't have any mac or unknown data in your database, you will not get any result to this platform, not even 0. What you can do is to have a preconfigured array with the platforms you are expecting to get:
$data = array(
'windows' => 0,
'linux' => 0,
'mac' => 0,
'unknown' => 0
)
Now in your get_platforms function do this:
function get_platforms() {
$query = "
SELECT platform, COUNT(platform) AS num
FROM stats
GROUP BY platform
ORDER BY platform ASC
";
$select = mysqli_query($this->c, $query);
while ($row = mysqli_fetch_array($select)) {
$data[$row['platform']] = $row['num'];
}
return $data;
}
you will end up with this:
$data = array(
'windows' => 3,
'linux' => 3,
'mac' => 0,
'unknown' => 0
)
And then you can reformat the data in the way that you want. For example you can do this:
$result = array();
foreach($data as $platform => $count){
$result[] = array('name' => $platform, 'count' => $count);
}
And you will end up with the result in the same format you're asking.

First of all you should define an order of desired output, lets say you have array
$osList = array('linux', 'windows', 'mac', 'something');
Now fetch your mysql results to temporary assoc array:
$data = array();
$query = "SELECT platform, COUNT(platform) AS num"
. " FROM stats"
. " GROUP BY platform";
$result = mysqli_query($this->c, $query);
while ($row = mysqli_fetch_array($result)) {
$data[$row['platform']] = (int) $row['num'];
}
And here you can form output array:
$output = array();
foreach ($osList as $os) {
$output[] = array(
'name' => $os,
'count' => isset($data[$os]) ? $data[$os] : 0
);
}

You must have another table which has all the platforms listed there. For example we call it platforms which has a column platform_name with all the unique names of platforms (including mac), then the query would be:
SELECT platforms.`platform_name`, COUNT(stats.`platform`) FROM `platforms`
LEFT JOIN `stats` ON platforms.`platform_name` = stats.`platform`
GROUP BY platforms.`platform_name`

Related

Two while loops to single array?

I'm trying to take parts number from two different tables and put them in the same array, then rearrange them.
Strangely it gives parts number twice, but when I run the same query in phpmyadmin it gives each part number once. I spend whole day but could not correct this.
//first query
$finalData = array(); $sql="SELECT
jobc_parts_p.part_no,
SUM(jobc_parts_p.issued_qty) AS sale_qty FROM
`jobc_parts_p` WHERE DATE_FORMAT(jobc_parts_p.date_time,'%Y-%m-%d') BETWEEN '".$f."' AND '".$t."'
GROUP BY jobc_parts_p.part_no";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()){
$finalData[$row['part_no']][] = $row;
}
//second query
$sql2="SELECT
jobc_consumble_p.part_no,
SUM(jobc_consumble_p.issued_qty) AS csale_qty
FROM
`jobc_consumble_p`
WHERE DATE_FORMAT(jobc_consumble_p.date_time,'%Y-%m-%d') BETWEEN '".$f."' AND '".$t."'
GROUP BY
jobc_consumble_p.part_no";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()){
$finalData[$row['part_no']][] = $row;
}
/// rearanging data......
$rearrangedFinalData = array();
foreach($finalData AS $first) {
foreach($first AS $data) {
$temp = array();
$temp['part_no'] = $data['part_no'];
$temp['sale_qty'] = isset($data['sale_qty']) ? $data['sale_qty'] : $data['csale_qty'];
$rearrangedFinalData[] = $temp;
}
}
//output result
foreach($rearrangedFinalData AS $row) {
$sr++;
echo "<tr><td>$sr</td>
<td colspan='2' >",$row["part_no"],"</td>
<td align='center'>",$row["sale_qty"],"</td>
</tr>";
}
RESULT
1 10R46 2
2 10R46 2
3 10R91 1
4 10R91 1
5 10M95 3
6 10M95 3
What i want:
1 10R46 2
2 10R91 1
3 10M95 3
First query print_r($finalData);
Array (
[10R46 ] => Array ( [0] => Array ( [part_no] =>
10R46 [sale_qty] => 1 ) )
[10R91 ] => Array ( [0] => Array ( [part_no] =>
10R91 [sale_qty] => 3 ) ))
Because, you are looping twice:
Modify
$rearrangedFinalData = array();
foreach($finalData AS $first) {
foreach($first AS $data) { // <-- Remove this extra loop.
$temp = array();
$temp['part_no'] = $data['part_no'];
$temp['sale_qty'] = isset($data['sale_qty']) ? $data['sale_qty'] : $data['csale_qty'];
$rearrangedFinalData[] = $temp;
}
}
To:
$rearrangedFinalData = array();
foreach($finalData AS $first) {
$temp = array();
$temp['part_no'] = $first['part_no'];
$temp['sale_qty'] = isset($first['sale_qty']) ? $first['sale_qty'] : $data['csale_qty'];
$rearrangedFinalData[] = $temp;
}
I think your problem lies within the $finalData where you store same results twice. (ofcourse from different tables though).
the first query creates a result of
$finalData = array(
'10R46' => array(0 => array('part_no' => 10R46, 'sale_qty' => 2)),
'10R91' => array(0 => array('part_no' => 10R91, 'sale_qty' => 1)),
'10M95' => array(0 => array('part_no' => 10M95, 'sale_qty' => 2))
);
then you run the second query and ADD to the finaldata again with this $finalData[$row['part_no']][] = $row;
so the $finalData is now something like
$finalData = array(
'10R46' => array(0 => array('part_no' => 10R46, 'sale_qty' => 2), 1 => array('part_no' => 10R46, 'csale_qty' => 2)),
'10R91' => array(0 => array('part_no' => 10R91, 'sale_qty' => 1), 1 => array('part_no' => 10R91, 'csale_qty' => 1)),
'10M95' => array(0 => array('part_no' => 10M95, 'sale_qty' => 3), 1 => array('part_no' => 10M95, 'csale_qty' => 3))
);
That is the reason why you double loop it and also get double results.
So i would combine the queries.
$sql="SELECT
jobc_parts_p.part_no,
SUM(jobc_parts_p.issued_qty) AS sale_qty,
SUM(jobc_consumble_p.issued_qty) AS csale_qty ## this part was added
FROM `jobc_parts_p`
LEFT JOIN `jobc_consumable_p` ON (jobc_consumable_p.part_no = jobc_parts_p.part_no) ## this part was added
WHERE DATE_FORMAT(jobc_parts_p.date_time,'%Y-%m-%d') BETWEEN '".$f."' AND '".$t."'
GROUP BY jobc_parts_p.part_no";
and now your result should look something like this without the secondquery
$finalData = array(
'10R46' => array(0 => array('part_no' => 10R46, 'sale_qty' => 2, 'csale_qty' => 2)),
'10R91' => array(0 => array('part_no' => 10R91, 'sale_qty' => 1, 'csale_qty' => 1)),
'10M95' => array(0 => array('part_no' => 10M95, 'sale_qty' => 2, 'csale_qty' => 3))
);
also if you don't expect there would be two rows with same part_no you can change
$finalData[$row['part_no']][] = $row; -> $finalData[$row['part_no']] = $row;
So you don't need to double loop it.
$new_array = array_values(array_unique($rearrangedFinalData));
Remove the duplicates and rearrange the keys (if needed) before you put your array in the foreach.
Then you can use the $new_array to generate your html

How to build an associative array with 2 sqls?

I want to build an associative array, which will run two mysql tables.
Name of tables: cs_lots , cs_lots_history .
My PHP CODE -
$rows = array();
$res2 = mysql_query("SELECT * FROM cs_lots WHERE active_lot='1'") or die(mysql_error());
$result1 = mysql_query("SELECT DISTINCT id_lot FROM cs_lots_history WHERE user_steamid='".$_SESSION['steamid']."'") or die(mysql_error());
while($row = mysql_fetch_array($res2)) {
$rows []= array(
'id' => $row['id'],
'inv_id' => $row['inv_id'],
'inv_assets' => $row['inv_assets'],
'name' => $row['inv_name'],
'inv_image' => $row['inv_image'],
'inv_rarity' => $row['inv_rarity'],
'inv_color' => $row['inv_color'],
'inv_type' => $row['inv_type'],
'inv_price' => $row['inv_price'],
'price_ticket' => $row['price_ticket'],
'maxUsers' => $row['places'],
'nowUsers' => $row['now_places'],
'my' => false
);
}
Array with this code:
LOTS = [{"id":"166","inv_id":"989","inv_assets":"3432669422","name":"Redline ","inv_image":"image","inv_rarity":"Field-Tested","inv_color":"d32ce6","inv_type":"1","inv_price":"2105.97","price_ticket":"14","maxUsers":"240","nowUsers":"1","my":false},
{"id":"167","inv_id":"929","inv_assets":"3551634073","name":"Hyper Beast ","inv_image":"image","inv_rarity":"Battle-Scarred","inv_color":"eb4b4b","inv_type":"1","inv_price":"924.43","price_ticket":"8","maxUsers":"180","nowUsers":"0","my":false},
{"id":"168","inv_id":"1104","inv_assets":"3313740799","name":"Asiimov ","inv_image":"image","inv_rarity":"Battle-Scarred","inv_color":"eb4b4b","inv_type":"1","inv_price":"1495.00","price_ticket":"13","maxUsers":"180","nowUsers":"19","my":false},
{"id":"169","inv_id":"847","inv_assets":"3603670527","name":"Jaguar ","inv_image":"image","inv_rarity":"Battle-Scarred","inv_color":"eb4b4b","inv_type":"1","inv_price":"2711.65","price_ticket":"13","maxUsers":"320","nowUsers":"8","my":false},
{"id":"170","inv_id":"1100","inv_assets":"3313741398","name":"Asiimov ","inv_image":"image","inv_rarity":"Field-Tested","inv_color":"eb4b4b","inv_type":"1","inv_price":"2756.70","price_ticket":"16","maxUsers":"260","nowUsers":"10","my":false},
{"id":"171","inv_id":"899","inv_assets":"3551642235","name":"Atomic Alloy ","inv_image":"image","inv_rarity":"Factory New","inv_color":"d32ce6","inv_type":"1","inv_price":"862.50","price_ticket":"8","maxUsers":"180","nowUsers":"1","my":false}];
Now my array running with one mysql table and i have only my:false But i need change key my and value false to true where SQL $result1 have same result $result1['id_lot'] with $row['id'] .
As Example: If $result1['id_lot'] = $row['id'] i need this code:
{"id":"166","inv_id":"989","inv_assets":"3432669422","name":"Redline ","inv_image":"image","inv_rarity":"Field-Tested","inv_color":"d32ce6","inv_type":"1","inv_price":"2105.97","price_ticket":"14","maxUsers":"240","nowUsers":"1","my":true}`
Thanks.
LEFT JOIN + aliases:
$rows = array();
$res2 = mysql_query("SELECT cs_lots_history.id, cs_lots_history.user_steamid, cs_lots_history.id_lot, cs_lots.id as csid, inv_id, inv_assets, inv_image, inv_color, inv_name, inv_rarity, inv_type, inv_price, price_ticket, places, now_places FROM cs_lots LEFT JOIN cs_lots_history ON cs_lots.id = cs_lots_history.id_lot WHERE active_lot='1' OR user_steamid='".$_SESSION['steamid']."' GROUP BY cs_lots.id") or die(mysql_error());
$a=0;
while($row = mysql_fetch_array($res2)) {
$rows []= array(
'id' => $row['csid'],
'inv_id' => $row['inv_id'],
'inv_assets' => $row['inv_assets'],
'name' => $row['inv_name'],
'inv_image' => $row['inv_image'],
'inv_rarity' => $row['inv_rarity'],
'inv_color' => $row['inv_color'],
'inv_type' => $row['inv_type'],
'inv_price' => $row['inv_price'],
'price_ticket' => $row['price_ticket'],
'maxUsers' => $row['places'],
'nowUsers' => $row['now_places'],
'my' => !empty($row['id_lot']) ? true : false
);
}
Thanks #Sean.

PHP mongo aggregation: match multiple values on same field

I need the pipeline to match documents where field 'modelName' is equal to 'movies' or 'tv_shows'. I tried the code below but it matches only 'tv_shows' and ignores 'movies'.
$match = array('$match' => array('modelName' => 'movies', 'modelName' => 'tv_shows'));
Whole script:
<?php
$connection = new MongoClient;
$collection = $connection -> selectDB("getglue") -> selectCollection("gg");
MongoCursor::$timeout = -1;
$match = array('$match' => array('modelName' => 'movies', 'modelName' => 'tv_shows'));
$group = array('$group' => array('_id' => '$title', 'total' => array('$sum' => 1)));
$sort = array('$sort' => array('total' => -1));
$limit = array('$limit' => 7);
$pipeline = array($match, $group, $sort, $limit);
$out = $collection -> aggregate($pipeline);
echo json_encode($out, JSON_PRETTY_PRINT);
?>
Make use of the $or operator:
$match = array('$match' =>
array('$or' => array(array("modelName" => "movies"),
array("modelName" => "tv_shows"))
)
);
An array in PHP is actually an ordered map. A map can have only one value for any key, and the last added value will override any previous values for the same key. So, in the below, tv_shows which is the last added value for the key - modelName will be associated as the key's only value. And that is why you get the results only for modelname of tv_shows.
'$match' => array('modelName' => 'movies', 'modelName' => 'tv_shows')

php array operations with indexes

I have a array what I'm fetching with mysql query per row, each containing the same indexes and it looks as it follows
array(
0=> array(
'order_nr'=> 123,
'order_date' => '2013-01-29 00:00:00',
'prod_name' => 'prod_1',
'prod_value' => 1200
)
1=> array(
'order_nr'=> 123,
'order_date' => '2013-01-29 00:00:00' ,
'prod_name' => 'prod_2',
'prod_value' => 2100
)
)
I would like to merge theme and make the sum of prod_value and creating a new array on prod_name and at the end I would have singe array. How would I do this in php or what would be the best workaround in this case
array(
'order_nr'=> 123,
'order_date'=>'2013-01-29 00:00:00',
'prod_name'=> array('prod_1', 'prod_2')
'prod_value' => 3300
)
If the list of products doesn't have to be an array you can use Mysql and aggregating functions. It would be something like this:
SELECT order_no, order_data, GROUP_CONCAT(prod_name SEPARATOR ',') as prod_name,
SUM(prod_value) as prod_val FROM Products WHERE ... GROUP BY order_no;
If you need the product names as arrays you can then explode the string:
explode(',', $row['prod_name']);
$aReturn = array();
foreach( $aData as $entry ) {
if( empty($aReturn[$entry['order_nr']]) ) {
$entry['prod_name'] = (array) $entry['prod_name'];
$aReturn[$entry['order_nr']] = $entry;
continue;
}
$aReturn[$entry['order_nr']]['prod_name'][] = $entry['prod_name'];
$aReturn[$entry['order_nr']]['prod_value'] += $entry['prod_value'];
}
This will group by order_nr
<?php
$arr = array(0=> array(
'order_nr'=> 123,
'order_date' => '2013-01-29 00:00:00',
'prod_name' => 'prod_1',
'prod_value' => 1200
),
1=> array(
'order_nr'=> 123,
'order_date' => '2013-01-29 00:00:00' ,
'prod_name' => 'prod_2',
'prod_value' => 2100
)
);
$sigle_arr = array();
foreach($arr as $val){
$sigle_arr[$val['order_nr']]['order_nr'] = $val['order_nr'];
$sigle_arr[$val['order_nr']]['order_date'] = $val['order_date'];
$sigle_arr[$val['order_nr']]['prod_name'][] = $val['prod_name'];
$sigle_arr[$val['order_nr']]['prod_value'] += $val['prod_value'];
}
print_r($sigle_arr);
?>
use array_merge_recursive()
that is the best option for doing it
$newarray = array();
foreach($array as $v){
if(!isset($newarray['order_nr'])){
$newarray['order_nr'] = $v['order_nr'];
}
if(!isset($newarray['order_date'])){
$newarray['order_date'] = $v['order_date'];
}
$newarray['prod_name'][] = $v['prod_name'];
$newarray['prod_value'] = $newarray['prod_value'] + $v['prod_value'];
}
$temp = Users::find('all', array('conditions' => array('status' => array('$elemMatch' => array('fields' => array('temp')));
foreach($whichs as $which)
{
foreach($which['temps'] as $temp)
{
if($temp['_id'] == $status['temp'])
{
array_push($tempsArray,$temp['status']);
}
}
}

How to write two colums table as an array?

I have a simple table with 2 colums: ID and Name. It looks like this:
License_ID License_Name
5 xxx
8 yyy
13 zzz
I want to write this table as an array, and I want to be able to find the license_id when license_name is provided. How can I write this array?
Edit: I can write the array the same as the answer nickb provided,
$array = array(
'xxx' => 5,
'yyy' => 8,
'zzz' => 13
);
but I want to have the license_id and license_name as key instead of using value of license_name as key.
Form an array with keys corresponding to the license name and values corresponding to the license ID, like so:
$sql = 'SELECT * FROM table'; // Optionally add a WHERE clause
$result = mysql_query( $sql);
$array = array();
while( $row = mysql_fetch_array( $result))
{
// Form the array
$array[ $row['License_Name'] ] = $row['License_ID'];
}
mysql_free_result( $result);
To omit the table and use a global variable, use the same technique:
$array = array(
'xxx' => 5,
'yyy' => 8,
'zzz' => 13
);
Now, to lookup the license ID, all you need is:
$license_id = 8;
$id = $array[ $license_id ]; // $id = 'yyy';
Edit: Here's an alternative way to represent the way in a more clear manner:
$array = array(
array(
'license_id' => 5,
'license_name' => 'xxx'
),
array(
'license_id' => 8,
'license_name' => 'yyy'
),
array(
'license_id' => 13,
'license_name' => 'zzz'
)
);
Then, to find the license_id when license_name is provided, loop to find your result:
$license_name = 'zzz';
foreach( $array as $entry)
{
if( $entry['license_name'] == $license_name)
{
echo 'Found ID of ' . $license_name . ' - ' . $entry['license_id'];
break;
}
}
OR, and even more direct way to prevent looping is to modify the above technique to have each sub-array contain the license_name as its key, like so:
$array = array(
'xxx' => array(
'license_id' => 5,
'license_name' => 'xxx'
),
'yyy' => array(
'license_id' => 8,
'license_name' => 'yyy'
),
'zzz' => array(
'license_id' => 13,
'license_name' => 'zzz'
)
);
Now, to find the license_id, you can do it directly once you know the license_name:
$license_name = 'zzz';
$license_id = $array[ $license_name ]['license_id'];
You know there is array_search out there,don't you? Personally I like to keep array keys as ids or numeric value.. so in your example $key=array_search('xxx',$myArr); (where id is the key and name is the value) http://php.net/manual/en/function.array-search.php

Categories