php sort after query fired - php

I want to sort highest to lowest cip and also lowest to highest cip, but cip value is not stored in database, it is calculated as soon as query is fired.
Here is html code to select sorting:
<select name="cip">
<option>Select CIP percentage</option>
<option value="1">Highest To Lowest</option>
<option value="2">Lowest To Highest</option>
</select>
And here is the query that I fired!
$select_applicant = "SELECT j.*, u.id, u.gender
FROM job_apply j
LEFT JOIN users u
ON u.id = j.user_id
WHERE j.job_id = '".$jid."'";
$result_applicant = mysqli_query($con, $select_applicant);
while($row_applicant = mysqli_fetch_assoc($result_applicant))
{
$user_id = $row_applicant["user_id"];
$user_info = get_user_profile_info($user_id);
$ratings_dist = get_skill_ratings_stats($user_id);
$got_it_total_rating = 0;
foreach($ratings_dist as $category=>$rating)
{
$got_it_total_rating = $got_it_total_rating + $rating['score'];
}
$got_it_total_category = count($ratings_dist);
$total_cip = ceil($got_it_total_rating / $got_it_total_category);
echo $total_cip;
}
Function "get_skill_ratings_stats" in php is as below:
function get_skill_ratings_stats($user_id){
global $con;
$items = array();
if($user_id>0)
{
$sql = "SELECT
s.category_id category_id,
c.name as category,
COALESCE(r.score_quality, 0.0) quality,
COALESCE(r.score_timing, 0.0) timing,
COALESCE(r.score_budget, 0.0) budget,
COALESCE(r.score_resp, 0.0) resp,
COALESCE(r.score_pro, 0.0) pro
FROM `user_skills` s
LEFT JOIN `skill_categories` c
ON c.category_id=s.category_id
LEFT JOIN `skill_ratings` r
ON r.skill_id=s.skill_id
WHERE s.user_id = '".(int)$user_id."'
AND s.status = 'active'
ORDER BY category ASC";
$prev_cat = '';
$result = mysqli_query($con, $sql);
// die(mysqli_error($con));
while($row = mysqli_fetch_assoc($result))
{
// print_r($row);
if(!$row['category']) continue;
if($row['category']!=$prev_cat)
{
if(isset($items[$prev_cat]['score']) && $items[$prev_cat]['score']>0 && count($items[$prev_cat])>1)
{
$items[$prev_cat]['score'] = floor(($items[$prev_cat]['score']*20)/(count($items[$prev_cat])-1));
}
$prev_cat = $row['category'];
}
if(!isset($items[$prev_cat]['score'])) $items[$prev_cat]['score'] = 0;
$items[$prev_cat][] = $row;
$items[$prev_cat]['score'] += ($row['quality']+$row['timing']+$row['budget']+$row['resp']+$row['pro'])/5;
}
}
// print_r($items);
// die();
if(isset($items[$prev_cat]['score']) && $items[$prev_cat]['score']>0 && count($items[$prev_cat])>1)
{
$items[$prev_cat]['score'] = floor(($items[$prev_cat]['score']*20)/(count($items[$prev_cat])-1));
}
$tmp = array();
foreach($items as $cat=>$item) {
$tmp[$item['score'].'-'.$cat] = $item;
}
krsort($tmp);
$items = array();
foreach($tmp as $k=>$v) {
$k = preg_replace('#^\d+-#is', '', $k);
$items[$k] = $v;
}
// print_r($tmp);
// print_r($items);
// die();
return $items;
}
Please help me! Having hard time with this!

Assuming that you are using a html table to display this I would just go with http://datatables.net/ , it will give you a lot of sorting options very easily...
Otherwise usort():
function cip($a, $b)
{
if ($a['cip'] == $b['cip']) {
return 0;
}
return ($a['cip'] < $b['cip']) ? -1 : 1;
}
$data = array(
[0] => array('cip' => 1)
[1] => array('cip' => 5)
[2] => array('cip' => 2)
);
usort($data, "cip");
foreach ($a as $key => $value) {
echo "$key: $value\n";
}
Assuming your array looks something like this:
array(
[0] => array('cip' => 1)
[1] => array('cip' => 5)
[2] => array('cip' => 2)
)
It basically loops til everything is sorted, all you do in the call back function is tell it which values to compare...
EDIT:
$total_cips[] = array('user_id' => $user_id, 'cip' => ceil($got_it_total_rating / $got_it_total_category));
Ok So now you have all the total cips in an array with there user_id right?
And outside for loop you call usort($total_cips, "cip");
Then you have a sorted array, if you wish to change the sorting direction just change the greater than to a less than in the cip function

as We0 said,
$total_cips[] = array('user_id' => $user_id, 'cip' => ceil($got_it_total_rating / $got_it_total_category));
but then i used multisort function:
function multi_sort($array, $akey)
{
function compare($a, $b)
{
global $key;
return strcmp($a[$key], $b[$key]);
}
usort($array, "compare");
return $array;
}
And then I call the function as below:
$total_cips = multi_sort($total_cips, $key = 'cip');
Finally this one worked!
Anyways thanks We0 & Ankit

Here:
$select_applicant = "SELECT j.*, u.id, u.gender
FROM job_apply j
LEFT JOIN users u
ON u.id = j.user_id
WHERE j.job_id = '".$jid."";
You are missing closing quote for $jid. It should be:
$select_applicant = "SELECT j.*, u.id, u.gender
FROM job_apply j
LEFT JOIN users u
ON u.id = j.user_id
WHERE j.job_id = '".$jid."'";
This might be one of the cause of your problem.

Related

Multiple nested array from MySQL query in PHP

I'm using foreach loops to access records in a nested array.
I need to nest 3 arrays (so the first array contains an array, which also contains an array). I'm having success with 2 arrays but I can't get 3 to work.
I had my code working with 2 arrays (which worked just fine) but I can't get 3 arrays to be nested.
This is the result that I want:
[
{
"site_id": "1",
"user_plants": [
{
"user_plant_id": "1",
"site_id": "1",
"plant_id": "1",
"plant_images": [
{
"plant_image_id": "1"
},
{
"plant_image_id": "2"
},
{
"plant_image_id": "3"
},
]
}
]
}
]
My current code:
$query = "SELECT A.site_id FROM sites A WHERE A.user_id='".$user_id."' GROUP BY A.site_id";
$result = $this->conn->query($query);
$json_response = array();
$sites = array();
if ($result-> num_rows > 0) {
while ($item = $result->fetch_object())
$sites[] = $item;
foreach($sites as $item) {
$row_array = (array)$item;
$site_id = $item->site_id;
$user_plants = "SELECT A.user_plant_id, A.site_id, A.plant_id FROM user_plants A RIGHT JOIN sites B ON A.site_id ='".$site_id."'
JOIN plants C ON A.plant_id = C.plant_id GROUP BY A.user_plant_id";
$resultSet = $this->conn->query($user_plants);
$user_plants = array();
if ($resultSet-> num_rows > 0) {
while ($item = $resultSet->fetch_object())
$user_plants[] = $item;
foreach ($user_plants as $item) {
$row_array['user_plants'][] = (array)$item;
$plant_id = $item->plant_id;
$user_plant_id = $item->user_plant_id;
$plant_images = "SELECT A.plant_image_id FROM plants_images A WHERE A.plant_id ='".$plant_id."' UNION SELECT B.plant_image_id FROM user_plant_image B JOIN user_plants C ON B.user_plant_id ='".$user_plant_id."' WHERE C.user_id ='".$user_id."' GROUP BY B.plant_image_id ORDER BY plant_image_id";
$resultSet = $this->conn->query($plant_images);
$plant_images = array();
if ($resultSet->num_rows > 0) {
while ($item = $resultSet->fetch_object())
$plant_images[] = $item;
foreach ($plant_images as $item) {
$row_array['user_plants'][]['plant_images'][] = $item;
}
} else if ($resultSet->num_rows == 0) {
$row_array['plant_images'] = [];
}
}
$json_response[] = $row_array;
}
}
}
return $json_response;
The result of above code:
[
{
"site_id": "1",
"user_plants": [
{
"user_plant_id": "1",
"site_id": "1",
"plant_id": "1"
},
{
"plant_images": [
{
"plant_image_id": "1"
},
{
"plant_image_id": "2"
},
{
"plant_image_id": "3"
},
]
}
]
}
]
How should I adjust the foreach loops above to cater for this?
There's plenty of room for improvement in this code but I've ignored that and tried to keep the code matching yours in this example.
The main changes are:
Create a temporary variable $user_plant_array which we store "plant_images" against
Push that temporary variable to the $site_array at the end of the loop
Rename some loop variables to making it easier to identify what you're referencing
$json_response = array();
$sites = array();
if ($result->num_rows > 0) {
while ($site = $result->fetch_object()) {
$sites[] = $site;
}
foreach ($sites as $site) {
$site_array = (array)$site;
$site_id = $site->site_id;
$user_plants = "SELECT A.user_plant_id, A.site_id, A.plant_id FROM user_plants A RIGHT JOIN sites B ON A.site_id ='" . $site_id . "'
JOIN plants C ON A.plant_id = C.plant_id GROUP BY A.user_plant_id";
$resultSet = $this->conn->query($user_plants);
$user_plants = array();
if ($resultSet->num_rows > 0) {
while ($user_plant = $resultSet->fetch_object())
$user_plants[] = $user_plant;
foreach ($user_plants as $user_plant) {
// create a temporary variable here that we will map
// all "plant_images" to
$user_plant_array = (array)$user_plant;
$plant_id = $user_plant->plant_id;
$user_plant_id = $user_plant->user_plant_id;
$plant_images = "SELECT A.plant_image_id FROM plants_images A WHERE A.plant_id ='" . $plant_id . "' UNION SELECT B.plant_image_id FROM user_plant_image B JOIN user_plants C ON B.user_plant_id ='" . $user_plant_id . "' WHERE C.user_id ='" . $user_id . "' GROUP BY B.plant_image_id ORDER BY plant_image_id";
$resultSet = $this->conn->query($plant_images);
$plant_images = array();
if ($resultSet->num_rows > 0) {
while ($plant_image = $resultSet->fetch_object())
$plant_images[] = $plant_image;
foreach ($plant_images as $plant_image) {
$user_plant_array['plant_images'][] = $plant_image;
}
} else if ($resultSet->num_rows == 0) {
$user_plant_array['plant_images'] = [];
}
// the temporary variable now contains all "plant_images"
// now we can push that to the site array
$site_array['user_plants'][] = $user_plant_array;
}
$json_response[] = $site_array;
}
}
}
return $json_response;
Creating a separate answer as an alternate solution with some code improvements.
"Improvements" being more readability and/or more performant.
A few of the main changes I would suggest as "improvements" have been implemented in this example. The main ones being:
Using prepared SQL statements (not always required but good practice to use, especially in anything accepting user input, also can make for cleaner code)
Reducing the amount of loops (in a few places you were looping just to create an array and then looping again)
Returning/continuing early where possible (helps to prevent unnecessary nesting)
Removing unnecessary if statements (e.g. most of the while loops will be skipped if the results are empty - checking beforehand isn't entirely necessary)
More readable variable names (it's common for new coders to try and abbreviate a lot of variables and often take it too far - making them readable will save you a lot of time when debugging)
The code using mysqli might not be the best as I generally work with PDO.
function getSitesData() {
// assumes that $user_id is set somewhere before this
// assumes that $this->conn references a valid database connection
$sql = "SELECT A.site_id FROM sites A WHERE A.user_id = ? GROUP BY A.site_id";
$query = $this->conn->prepare($sql);
$query->bind_param("i", $user_id);
$query->execute();
$site_result = $query->get_result();
$sites = [];
while ($site = $site_result->fetch_assoc()) {
// using fetch_assoc gives us an associative array
// initialise empty array
$site["user_plants"] = [];
// get user_plants
$sql = "SELECT A.user_plant_id, A.site_id, A.plant_id FROM user_plants A RIGHT JOIN sites B ON A.site_id = ?
JOIN plants C ON A.plant_id = C.plant_id GROUP BY A.user_plant_id";
$query = $this->conn->prepare($sql);
$query->bind_param("i", $site["site_id"]);
$query->execute();
$user_plant_result = $query->get_result();
while ($user_plant = $user_plant_result->fetch_assoc()) {
// intialise empty array
$user_plant["plant_images"] = [];
// get plant images
$sql = "SELECT A.plant_image_id FROM plants_images A WHERE A.plant_id = ? UNION SELECT B.plant_image_id FROM user_plant_image B JOIN user_plants C ON B.user_plant_id = ? WHERE C.user_id = ? GROUP BY B.plant_image_id ORDER BY plant_image_id";
$query = $this->conn->prepare($sql);
$query->bind_param("iii", $user_plant["plant_id"], $user_plant["user_plant_id"], $user_id);
$query->execute();
$plant_image_result = $query->get_result();
while ($plant_image = $plant_image_result->fetch_assoc()) {
$user_plant["plant_images"][] = $plant_image;
}
$sites["user_plants"][] = $user_plant;
}
$sites[] = $site;
}
return $sites;
}

Error coming when table is empty in mysql, How to solve?

I have query in php
select
c.*,
CONCAT(c.first_name, ' ' ,c.middle_name, ' ' ,c.last_name) as name,
r.paid_amount as total_amount_paid,
r.emi_date as emi_date_from_reciept,
ltc.loan_amount as total_remaining_loan_amount ,
ltc.emi_date as emi_loan_date,
ltc.no_of_month as num_of_months_from_ltc
FROM loan_to_customer ltc
LEFT JOIN customer c ON ltc.customer_id = c.customer_id
LEFT JOIN receipt r ON r.customer_id = c.customer_id
WHERE c.cust_mobile = '$cust_mobile' OR c.unique_no = '$unique_no'
I am getting this error
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1`
I am getting this error while my table is empty.
If I execute this on phpmyadmin it simply run and success.
My php code is like this
<?php
include "connection.php";
extract($_REQUEST);
$data = array();
$resArr = array();
$query = customSelectQuery("select c.*, CONCAT(c.first_name, ' ' ,c.middle_name, ' ' ,c.last_name) as name,r.paid_amount as total_amount_paid,
r.emi_date as emi_date_from_reciept, ltc.loan_amount as total_remaining_loan_amount ,
ltc.emi_date as emi_loan_date, ltc.no_of_month as num_of_months_from_ltc FROM loan_to_customer ltc
LEFT JOIN customer c ON ltc.customer_id = c.customer_id
LEFT JOIN receipt r ON r.customer_id = c.customer_id
WHERE c.cust_mobile = '$cust_mobile' OR c.unique_no = '$unique_no'");
if (isset($query)) {
$ltc_data = array();
foreach ($query as $row) {
$ltc_data = array(
'loan_amount' => $row['loan_amount'],
'total_remaining_loan_amount' => $row['total_remaining_loan_amount'],
'no_of_month' => $row['no_of_month'],
"num_of_months_from_ltc"=>$row['num_of_months_from_ltc'],
"emi_date_from_reciept" => $row['emi_date_from_reciept'],
"customer_id"=>$row['customer_id'],
);
}
}
$customer_id = $ltc_data['customer_id'];
$query1 = customSelectQuery("SELECT * FROM receipt WHERE customer_id = $customer_id");
$penalty_amoount = '100';
$paid_emi_date = array();
foreach ($query1 as $row1) {
$paid_emi_date[] = array('date'=>$row1['emi_date'],'amount'=>$row1['paid_amount'], 'penalty_amoount'=>$penalty_amoount);
}
$loan_amount = $ltc_data['loan_amount'];
$total_remaining_loan_amount = $ltc_data['total_remaining_loan_amount'];
$total_amount_paid = $loan_amount - $total_remaining_loan_amount;
$no_of_month = $ltc_data['no_of_month'];
$num_of_months_from_ltc = $ltc_data['num_of_months_from_ltc'];
$total_paid_emi_month = $no_of_month - $num_of_months_from_ltc;
$penalty_amoount1 = '20';
if (sizeOf($query) > 0) {
$d = array();
foreach ($query as $row) {
// $output = [];
foreach ( explode(',', $row['emi_loan_date']) as $date ) {
$output[] = ['date' => $date, 'emi_amount' => $row['emi_amount'], 'penalty_amoount'=>$penalty_amoount1];
}
$emi_date1 = $output[0]['date'];
$emi_a = $output[0]['emi_amount'];
$p_amo = $output[0]['penalty_amoount'];
$f_a = $emi_a + $p_amo;
$d[] = array(
"name" => $row['name'],
"Loan_Account_No" => $row['unique_no'],
"product_amount"=> $row['product_amount'],
"num_of_months" => $row['num_of_months'],
"no_of_month" => $no_of_month,
"loan_amount" => $row['loan_amount'],
"total_paid_emi_month" =>$total_paid_emi_month,
'total_amount_paid' => $total_amount_paid,
'total_remaining_loan_amount' => $row['total_remaining_loan_amount'],
"pending_emi_amount"=>$f_a,
"pending_emi_date"=>$emi_date1,
// "emi_date1" => explode(',', $row['emi_loan_date']),
"emi_date1" =>$output,
"paid_emi_date"=> $paid_emi_date,
"start_emi_date"=> $row['loan_date'],
"emi_amount"=> $row['emi_amount'],
// "emi_pending_amount"=>
);
}
}
if($d === null){
$d = " ";
$message = "not found loan data.";
}
$resArr = array("success" => 1, "data" => $d, "message" => $message);
header('Content-Type: application/json');
echo str_replace("\/", "/", json_encode($resArr, JSON_UNESCAPED_UNICODE));
?>
replace '$cust_mobile' by '\''.$cust_mobile.'\'' and '$unique_no' by '\''.$unique_no.'\''. Because $cust_mobile and $unique_no are variables
select c.*, CONCAT(c.first_name, ' ' ,c.middle_name, ' ' ,c.last_name) as name,r.paid_amount as total_amount_paid,
r.emi_date as emi_date_from_reciept, ltc.loan_amount as total_remaining_loan_amount ,
ltc.emi_date as emi_loan_date, ltc.no_of_month as num_of_months_from_ltc FROM loan_to_customer ltc
LEFT JOIN customer c ON ltc.customer_id = c.customer_id
LEFT JOIN receipt r ON r.customer_id = c.customer_id
WHERE c.cust_mobile = '\''.$cust_mobile.'\'' OR c.unique_no = '\''.$unique_no.'\''

Echo nested JSON array from related database tables with a single query?

I have two database tables that contain information about land contracts. They are related with land_contract_annual_price.land_contract_id -> land_contract.land_contract_id.
Table 'land_contract'
Table 'land_contract_annual_price'
If a land contract has the value "Rörligt pris" in the field land_contract_price_type, there are related values in the table
land_contract_annual_price. At the moment I'm doing two queries, one to each table. I then merge the results and present the land contract as a nested JSON array like this:
Version 1
[
{
"land_contract_id":118,
"land_contract_name":"Avtalsnamn",
"location_id":71,
"land_contract_link":"",
"land_contract_notes":"",
"land_owner_id":2,
"land_contract_start_date":"2019-07-25",
"land_contract_end_date":"2023-07-25",
"land_contract_terminated":"false",
"land_contract_payment_interval":"Halv\u00e5rsvis",
"land_contract_price_type":"R\u00f6rligt \u00e5rspris",
"land_contract_fixed_annual_price":null,
"land_contract_annual_prices":[
{"year":1, "price":873.00},
{"year":2, "price":77289.00},
{"year":3, "price":8.00},
{"year":4, "price":0.00},
{"year":5, "price":8729.00}
]
}
]
If a land contract has the value "Fast pris" in the field land_contract_price_type, there are no related values in the table
land_contract_annual_price. In that case I present the land contract like this (without the extra array at the end):
Version 2
[
{
"land_contract_id":13,
"land_contract_name":null,
"location_id":null,
"land_contract_link":"https:\/\/www.something.com\/preview\/Sl%C3%A4pvdam%20Edda\/Kddal\/Bddkta\/Besika%20Markavtal%20%20Halmstad%202016-03-08.pdf?role=personal",
"land_contract_notes":"",
"land_owner_id":null,
"land_contract_start_date":"2016-03-08",
"land_contract_end_date":"2026-03-08",
"land_contract_terminated":"true",
"land_contract_payment_interval":"\u00c5rsvis",
"land_contract_price_type":"Fast \u00e5rspris",
"land_contract_fixed_annual_price":"6000.00"
}
]
What I didn't think of, is that this solution is bad when I'm fetchin ALL the land contracts. If I'm going to do a second query to another table whenever a land contract has the value "Rörligt pris" in the field land_contract_price_type, I'm going to do hundreds of extra queries.
Is there a way to create the nested JSON array with one (1) query when a land contract has the value "Rörligt pris" in the field land_contract_price_type?
Thanks!
Below is my current code.
function read($pdo, $Id = null, $ResponseMessage = null) {
$params = [];
$array = [];
$sql = "SELECT lc.Id, lc.Name, lc.LocationId, l.Name AS LocationName, lc.Notes, lc.LandOwnerId, lo.Name AS LandOwnerName, lc.StartDate, lc.EndDate, lc.IsTerminated, lc.PaymentInterval, lc.PriceType, lc.FixedAnnualPrice, lc.Link, lc.Created, lc.Updated, lcap.AnnualPriceYear AS Year, lcap.AnnualPriceAmount AS Amount
FROM LandContract lc
LEFT JOIN Location l ON l.Id = lc.LocationId
LEFT JOIN LandOwner lo ON lo.Id = lc.LandOwnerId
LEFT JOIN LandContractAnnualPrice lcap ON lcap.LandContractId = lc.Id
ORDER BY lc.Id DESC, lcap.AnnualPriceYear DESC
";
if ($Id) {
$sql .= 'WHERE lc.Id = ?';
$params[] = $Id;
}
echo $sql;
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
while ($row = $stmt->fetch()) {
// Fields we want to extract from the select statement into the array
$select_fields = ['Id', 'Name', 'LocationId', 'LocationName', 'Link', 'Notes', 'LandOwnerId', 'LandOwnerName',
'StartDate', 'EndDate', 'IsTerminated', 'PaymentInterval',
'PriceType', 'FixedAnnualPrice ', 'Created', 'Updated'];
if (!isset($array[$row['Id']])) {
// initialize the subarray if it has not been set already
$array[$row['Id']] = array_intersect_key($row, array_flip($select_fields));
if ($row['Year'] != null) {
$array[$row['Id']]['AnnualPrices'] = [];
} else {
$array[$row['Id']]['AnnualPrice'] = $row['FixedAnnualPrice'];
}
}
if ($row['Year'] != null) {
$array[$row['Id']]['AnnualPrices'][] = ['Year' => $row['Year'], 'Amount' => $row['Amount']];
}
}
if (empty($array)) {
$ResponseMessage = new ResponseMessage();
$ResponseMessage->Status = 'Error';
$ResponseMessage->Message = 'No results';
echo json_encode($ResponseMessage, JSON_UNESCAPED_UNICODE);
exit;
}
$Response = array();
if ($ResponseMessage) {
$Response['Status'] = $ResponseMessage->Status;
$Response['Message'] = $ResponseMessage->Message;
}
$Response['LandContracts'] = array_values($array);
echo json_encode($Response, JSON_UNESCAPED_UNICODE);
$stmt = null;
}
You are better off using a JOIN query, and then structure your array from the result - having a query within a loop is often a very bad idea, and an indicator that you can use a JOIN instead.
You want to use a LEFT JOIN, joining them on the land_contract_id in both tables.
Then loop your results, and construct your array, which you can end up encoding into a JSON string once done.
$params = [];
$array = [];
$sql = "SELECT lc.*,
py.land_contract_annual_price_year AS `year`,
py.land_contract_annual_price_amount AS `amount`
FROM land_contract AS lc
LEFT JOIN land_contract_annual_price AS py
ON py.land_contract_id = lc.land_contract_id
";
if (isset($_POST['land_contract_id'])) {
$sql .= 'WHERE lc.land_contract_id = ?';
$params[] = $_POST["land_contract_id"];
}
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
while ($row = $stmt->fetch()) {
// Fields we want to extract from the select statement into the array
$select_fields = ['land_contract_id', 'land_contract_name', 'location_id', 'land_contract_link', 'land_contract_notes', 'land_owner_id',
'land_contract_start_date', 'land_contract_end_date', 'land_contract_terminated', 'land_contract_payment_interval',
'land_contract_price_type', 'land_contract_fixed_annual_price '];
if (!isset($array[$row['land_contract_id']])) {
// initialize the subarray if it has not been set already
$array[$row['land_contract_id']] = array_intersect_key($row, array_flip($select_fields));
if ($row['year'] != null) {
$array[$row['land_contract_id']]['land_contract_annual_prices'] = [];
} else {
$array[$row['land_contract_id']]['land_contract_annual_price'] = $row['land_contract_fixed_annual_price'];
}
}
if ($row['year'] != null) {
$array[$row['land_contract_id']]['land_contract_annual_prices'][] = ['year' => $row['year'], 'amount' => $row['amount']];
}
}
if (empty($array)) {
echo "No results";
exit;
}
echo json_encode($array, JSON_UNESCAPED_UNICODE);

How to deduce the count of the vacancies next to the name of the city?

I made a sql query that counts of jobs in a particular city
$countVac = Yii::app()->db->createCommand()
->select(array('cityId', 'count(*)'))
->from('mnk_vacancy')
->group('cityId')
->queryRow();
My function for deduce city
public function getCityList()
{
$cityList = $this->findAll(array('order' => 'name'));
$cityArray = CHtml::listData($cityList, 'id', 'name');
return $cityArray;
}
How do I make something like this
public function getCitiesWithVacanciesNumber()
{
//raw sql
$sql = '
SELECT
c.name city_name,
COUNT(v.id) vac_num
FROM cities c
LEFT JOIN mnk_vacancy v
ON v.cityId = c.id
GROUP BY c.name
';
return $this->getDbConnection()->createCommand($sql)->queryAll();
/*
AR:
'vacancies' => array(self::HAS_MANY, 'Vacancy', 'cityId', 'together' => true,)
*/
$rows = array();
$cities = self::model()->with('vacancies')->findAll();
foreach ($cities as $city) {
$rows[] = array(
'city_name' => $city->name,
'vac_num' => count($city->vacancies)
);
}
return $rows;
}

How to grab an array from a query

I have a function getCart which has a complicated query that is merged together. I want to select only one array that is $cart['tee_times'] = array(); and place that array in another function. How can I accomplish this?
Here is a snippet of the query I am trying to pull from.
function getCart($id, DBConnection $connection) {
$query = 'SELECT * FROM cart WHERE IDCart=:cart_id LIMIT 1';
$prepared = array(
"cart_id" => $id
);
$results = $connection->fetch($query, $prepared);
$cart = !empty($results) ? $results[0] : null;
if (isset($cart)) {
$cart['IDCustomer'] = isset($cart['IDCustomer']) ? (int)$cart['IDCustomer'] : null;
$cart['IDDestination'] = isset($cart['IDDestination']) ? (int)$cart['IDDestination'] : null;
$cart['total'] = 0;
$cart['tee_times'] = array();
$cart['rooms'] = array();
$cart['cars'] = array();
$query = '
SELECT
a.*,
e. city_name,
f.IDDestination,
((CASE DATE_FORMAT(a.teetime_dt, "%w")
WHEN 0 THEN b.sun
WHEN 1 THEN b.mon
WHEN 2 THEN b.tue
WHEN 3 THEN b.wed
WHEN 4 THEN b.thu
WHEN 5 THEN b.fri
WHEN 6 THEN b.sat
ELSE 0
END) * a.no_rounds * a.no_golfers) price,
c.tax_rate
FROM cart_course_teetimes a
JOIN course_priceplan b
ON b.IDCoursePricePlan = a.IDCoursePricePlan
JOIN course_tax c
ON c.IDCourseTax = a.IDCourseTax
JOIN course d
ON d.IDCourse = b. IDCourse
JOIN vw_cities e
ON e.IDCity = d. IDCity
JOIN destinations_cities f
ON f.IDCity = e.IDCity
WHERE IDCart=:cart_id
';
$results = $connection->fetch($query, $prepared);
foreach ($results as $row) {
$formatted = array(
'IDCartTeetimes' => (int)$row['IDCartTeetimes'],
'IDCoursePricePlan' => (int)$row['IDCoursePricePlan'],
'IDCourseTax' => (int)$row['IDCourseTax'],
'teetime_date' => $row['teetime_dt'],
'num_golfers' => (int)$row['no_golfers'],
'num_rounds' => (int)$row['no_rounds'],
'price' => (float)$row['price'],
'tax_rate' => (float)$row['tax_rate'],
'city_name' => $row['city_name'],
'IDDestination' => (int)$row['IDDestination'],
);
$cart['tee_times'][] = $formatted;
$cart['total'] += $formatted['price'];
}
Here is my function and my attempt at retrieving the tee_times array
function filterCart($cart_id, DBConnection $connection) {
$cart = getCart($cart_id, $connection);
if (!isset($cart)) {
http_response_code(404);
return 'Cart does not exist.';
}
$results =$cart['tee_times'];
echo $results;
$id = null;
foreach ($results as $row){
var_dump($row['IDDestination']);
If you want to filter out courses that have more than one IDDestination, change the WHERE clause to:
WHERE IDCart = :cart_id
AND IDCart NOT IN (
SELECT IDCart
FROM course a
JOIN destinations_cities b ON b.IDCity = a.IDCity
GROUP BY IDCart
HAVING COUNT(*) > 1)

Categories