How to build my JSON data with only one MySQL request? - php

Is it possible to get a JSON output looks like with one query?
[{
"name": "Date",
"data": ["2013-01-01", "2013-02-01", "2013-03-01", "2013-04-01", "2013-05-01"] //data from grouped from_date column
}, {
"name": "KD",
"data": [4, 5, 6, 2, 5] // arrays from saldo_sprzedazy for KD sales_group
}, {
"name": "SG",
"data": [5, 2, 3, 6, 7] // arrays from saldo_sprzedazy for SG sales_group
}]
My current query:
SELECT
sales_raport_all.from_date,
SUM(sales_raport_all.saldo_sprzedazy),
klienci_ax_all.sales_group,
klienci_ax_all.nazwa
FROM
sales_raport_all
INNER JOIN
klienci_ax_all
ON
sales_raport_all.konto=klienci_ax_all.konto_odbiorcy
WHERE
YEAR(from_date) = YEAR(CURDATE())
GROUP BY
sales_raport_all.from_date
I group by from_date but I need to also group by sales_group...
Is it possible to do this on the mysql table with I have?
i try to prepare data to Column Highcharts highcharts.com/demo/column-basic
EDIT:
OK, maybe this will clarify my earlier question :)
This is my PHP code:
$query = mysql_query("SELECT
sales_raport_all.from_date,
sales_raport_all.to_date,
sales_raport_all.konto,
SUM(sales_raport_all.saldo_sprzedazy),
SUM(sales_raport_all.wartosc_kosztowa),
SUM(sales_raport_all.marza),
klienci_ax_all.sales_group,
klienci_ax_all.nazwa
FROM
sales_raport_all
INNER JOIN
klienci_ax_all
ON
sales_raport_all.konto=klienci_ax_all.konto_odbiorcy
WHERE
YEAR(from_date) = YEAR(CURDATE())
GROUP BY
sales_raport_all.from_date");
$category = array();
$category['name'] = 'Data';
while($r = mysql_fetch_array($query)) {
$category['data'][] = $r['from_date'];
}
$querySG = mysql_query("SELECT
sales_raport_all.from_date,
sales_raport_all.to_date,
sales_raport_all.konto,
SUM(sales_raport_all.saldo_sprzedazy),
SUM(sales_raport_all.wartosc_kosztowa),
SUM(sales_raport_all.marza),
klienci_ax_all.sales_group,
klienci_ax_all.nazwa
FROM
sales_raport_all
INNER JOIN
klienci_ax_all
ON
sales_raport_all.konto=klienci_ax_all.konto_odbiorcy
WHERE
klienci_ax_all.sales_group = 'SG'
AND
YEAR(from_date) = YEAR(CURDATE())
GROUP BY
sales_raport_all.from_date");
$series1 = array();
$series1['name'] = 'SG';
while($r = mysql_fetch_array($querySG)) {
$series1['data'][] = intval($r['SUM(sales_raport_all.saldo_sprzedazy)']);
}
....
My question is: do I have to write a separate query for every specific sales_group or is there a simpler way?
Now I use json like this:
$result = array();
array_push($result,$category);
array_push($result,$series1);
array_push($result,$series2);
array_push($result,$series3);
print json_encode($result);

If you want to do this in one go, you have to group by both sales_group and from_date:
$query = mysql_query("SELECT
sales_raport_all.from_date,
sales_raport_all.to_date,
sales_raport_all.konto,
SUM(sales_raport_all.saldo_sprzedazy),
SUM(sales_raport_all.wartosc_kosztowa),
SUM(sales_raport_all.marza),
klienci_ax_all.sales_group,
klienci_ax_all.nazwa
FROM
sales_raport_all
INNER JOIN
klienci_ax_all
ON
sales_raport_all.konto=klienci_ax_all.konto_odbiorcy
WHERE
YEAR(from_date) = YEAR(CURDATE())
GROUP BY
sales_raport_all.from_date,
klienci_ax_all.sales_group
ORDER BY
sales_raport_all.from_date,
klienci_ax_all.sales_group");
Then collect all the possible dates and all the data in a raw array.
$raw = array();
$dates = array();
while ($r = mysql_fetch_array($query)) {
$date = $r['from_date'];
if (!in_array($date, $dates)) $dates[] = $date;
$sales_group = $r['sales_group'];
$raw[$sales_group][$date] = intval($r['SUM(sales_raport_all.saldo_sprzedazy)']);
}
Lastly go through the raw data, and check if on a given date the sales_group has relevant data or set it to zero.
$data = array();
$data[0] = array('name' => "Date", 'data' => $dates);
foreach ($raw as $name => $d) {
$new_data = array('name' => $name, 'data' => array());
foreach ($dates as $date) {
$new_data['data'][] = isset($d[$date]) ? $d[$date] : 0;
}
$data[] = $new_data;
}
The final $data will have the desired structure and all the data you need.

Related

Get variable in sql statment and use in php

The function below generates a table like the image below.
The location_id is being accessed but I would like to use this ID again at the bottom of the table in a link. See the LOCATION_ID at the bottom of the function.
Im not sure how to do this.
function countAppointment2() {
require 'config.php';
$data = array();
$date_list= array();
$sql_date_list ="SELECT start_date from appointment GROUP BY start_date";
$result_date_list = mysqli_query($conn, $sql_date_list);
$sql_loc_list = "SELECT `name` FROM `location` GROUP BY `name`";
$result_loc_list = mysqli_query($conn, $sql_loc_list);
$k=0;
while ($row =mysqli_fetch_assoc($result_loc_list)){
$data +=[$row['name']=>array()];
if($k==0){
while($row2 =mysqli_fetch_assoc($result_date_list)){
array_push($date_list,$row2['start_date']);
$data[$row['name']]+=[$row2['start_date']=>0];
}
$k++;
}else{
foreach($date_list as $date){
$data[$row['name']]+=[$date=>0];
}
}
}
$sql_getdata = "SELECT t2.name as loc_name, t1.start_date,t1.location_id, COUNT(t1.location_id) AS count FROM appointment t1 JOIN location t2 ON t1.location_id = t2.id GROUP BY t1.location_id,t1.start_date";
$result = mysqli_query($conn, $sql_getdata);
while($row =mysqli_fetch_assoc($result)){
$data[$row['loc_name']][$row['start_date']]=$row['count'];
}
$table="<table class='table table-bordered'>";
$table.="<thead><tr>";
$table.="<th>Dealership Location</th>";
foreach ($date_list as $date) {
$edate = date("d/m/Y", strtotime($date));
$table.="<th>".$edate."</th>";
}
$table.="</tr></thead>";
foreach ($data as $key=>$date) {
$table.="<tbody><tr>";
$table.="<td>".$key."</td>";
foreach($date as $key2=>$count){
$table.="<td>".$count."</td>";
}
$table.="</tr>";
}
$table.="</tbody></table>";
echo $table;
}
Change
$data[$row['loc_name']][$row['start_date']]=$row['count'];
to
$data[$row['loc_name']][$row['start_date']] = [
'count' => $row['count'],
'location_id' => $row['location_id']
];
Then replace the code in the loop to:
$table.="<td>".$count['count']."</td>";
Essentially changing it from a single value to an array.

Using PDO to get JSON from tow tables

I'm trying to get a JSON Object from two tables in the MySQL database, but nothing returned.
product table: id, title, description, price
product_colors table: id, product_id, product_color
My PHP code:
$st = $conn->prepare ('SELECT `product`.id , `product`.title, `product`.description, `product`.price, GROUP_CONCAT(`product_colors`.product_color) AS colors FROM `product` LEFT JOIN `product_colors` ON `product`.id = `product_colors`.product_id GROUP BY `product`.id');
$st->execute();
$products = [];
$rows = $st->fetchAll(\PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$row['product_colors'] = explode(',', $row['product_color']);
$products[] = $row;
}
echo json_encode ($products);
This what I want to get:
[
{
id: 4,
title: 'Car',
description: "Pellentesque orci lectus",
price: '120$',
product_color: ['Red', 'Blue', 'Black']
},
{
id: 6,
title: 'Bus',
description: "orci lectus",
price: '10$',
product_color: ['White', 'Blue', 'Green']
}
]
So finally i got the answer, first the query is correct and perfect, the error in fetching and loop, so this is the perfect solution and much easier:
$rows = array();
while($r = mysqli_fetch_assoc($sth)) {
$r['colors']=explode(',', $r['colors']); //colors like what i named the GROUP_CONCAT
$rows[] = $r;
Still considering PDO? You may want this...
<?php
$output = array();
$products = 'product'; // "product" Table
$colors = 'product_colors'; // "product_colors" Table
//if "id" is auto-incremented which may not match "product_id", You may want to create another "product_id" in $products table to use the $statement commented below
/*
$statement = $connection->prepare(
"SELECT t.product_id, t.title, t.description, t.price, c.product_color FROM `$products` t, `$colors` c WHERE t.product_id = c.product_id"
);
*/
$statement = $connection->prepare(
"SELECT t.id as product_id, t.title, t.description, t.price, c.product_color FROM `$products` t, `$colors` c WHERE t.product_id = c.product_id"
);
$statement->execute();
$result = $statement->fetchAll();
foreach($result as $row)
{
$output['id'] = $row['product_id'];
$output['title'] = $row['title'];
$output['description'] = $row['description'];
$output['price'] = $row['price'];
$output['product_color'] = explode(',', $row['product_color']);
}
echo json_encode($output);
?>

Query to get a all tags field values and pour all value in field

UPDATE :
i need get a all values of tags field !
MY Query :
$query = db_select('node', 'node');
$query->fields('tagsdata',array('name'));
$query->fields('node', array('nid'));
$query->leftJoin('field_data_field_tags', 'tags', 'tags.entity_id = node.nid');
$query->leftJoin('taxonomy_index', 'tagsindex', 'tagsindex.nid = tags.entity_id');
$query->leftJoin('taxonomy_term_data','tagsdata','tagsdata.tid = tags.field_tags_tid AND node.nid = tagsindex.nid');
$result = $query->execute();
while( $record = $result->fetchAssoc() ) {
$items[] = $record;
}
AND MY CODE :
//SORT
array_multisort(array_column($items, 'nid'), $items);
foreach ($items as $row) {
$hash[$row[nid]] = $row;
}
$resultfinal = ($hash);
// END SORT
foreach($resultfinal as $finalarrays)
{
$tags=$finalarrays['name'];
print_R ($tags);
}
WITH above code just return one and first value of tags, i need to print all of them !
You can use GROUP_CONCAT mysql function to get all value imploded by comma :
$result = db_query("SELECT tags.entity_id as nid, GROUP_CONCAT(t.name) as tdata FROM field_data_field_tags
INNER JOIN taxonomy_term_data t ON t.tid = tags.field_tags_tid
WHERE tags.entity_type = :type GROUP BY tags.entity_id",
array(':type' => 'node'))->fetchAllKeyed();
NB : sometimes you have too much string to concat so you need to increase limit before by :
db_query('SET SESSION group_concat_max_len=10000');
$result = db_query("SELECT tags.entity_id as nid, GROUP_CONCAT(t.name) as tdata FROM field_data_field_tags
INNER JOIN taxonomy_term_data t ON t.tid = tags.field_tags_tid
WHERE tags.entity_type = :type GROUP BY tags.entity_id",
array(':type' => 'node'))->fetchAllKeyed();
https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat
foreach($result as $nid => $tags) {
echo $nid . ' : '.$tags;
}

How to combine multiple queries into one and fetch data using single while loop?

I have this code how can I combine multiple queries and their result into one ?
<?php
$obj = new stdClass();
include('pdoConfig.php');
$response = array();
$sql1 = $dbh->prepare("select * from orders_assigned where delivery_status != 'Cancelled' && order_status='Picked'");
$sql1->execute();
$count1 = $sql1->rowCount();
if ($count1 >= 1) {
while ($row1 = $sql1->fetch()) {
$delivery_status = $row1['delivery_status'];
$deliveryboy_id = $row1['username'];
$order_id = $row1['order_id'];
$sql2 = $dbh->prepare("select * from delboy_login where id = ?");
$sql2->bindParam(1, $deliveryboy_id);
$sql2->execute();
$row2 = $sql2->fetch();
$del_name = $row2['name'];//name
$del_lat = $row2['lat'];//lat
$del_longi = $row2['longi'];//long
$del_icon = $row2['icon'];//icon
$sql3 = $dbh->prepare("select * from `order` where `order_id` = ?");
$sql3->bindParam(1, $order_id);
$sql3->execute();
$row3 = $sql3->fetch();
$address_id = $row3['address_id'];
$user_id = $row3['user_id'];
$sql4 = $dbh->prepare("select * from customer_login where cust_id = ?");
$sql4->bindParam(1, $user_id);
$sql4->execute();
$row4 = $sql4->fetch();
$cus_name = $row4['name'];//name
$sql5 = $dbh->prepare("select * from address where a_id = ?");
$sql5->bindParam(1, $address_id);
$sql5->execute();
$row5 = $sql5->fetch();
$cus_lat = $row5['lat'];//lat
$cus_longi = $row5['longi'];//long
$cus_icon = $row5['icon'];//icon
$tmp = array();
$tmp['lat'] = $del_lat;//i want use $cus_lat here too
$tmp['content'] = $del_name;//i want use $cus_name here too
$tmp['lng'] = $del_longi;//i want use $cus_longi here too
$tmp['icon'] = $del_icon;//i want use $cus_icon here too
array_push($response, $tmp);
}
}
echo json_encode($response, JSON_NUMERIC_CHECK);
Using this I can only get either $del_ data or $cus_ data I want use both. I have multiple tables for same data but I can not combine tables because both are different kind of users. As I am not good at joins so I don't know how to use joins here.
By using one of query provided below i am getting this
{
"delivery_status" : Delivered,
"username" : 1,
"order_id" : 5,
"del_name" : Boy One,
"del_lat" : 26.8808383,
"del_longi" : 75.7503407,
"address_id" : 31,
"user_id" : 1,
"cus_name" : Roylee Wheels,
"cus_lat" : 20.593684,
"cus_longi" : 78.96288
},
{
"delivery_status" : Processing,
"username" : 1,
"order_id" : 6,
"del_name" : Boy One,
"del_lat" : 26.8808383,
"del_longi" : 75.7503407,
"address_id" : 30,
"user_id" : 1,
"cus_name" : Roylee Wheels,
"cus_lat" : 20.594725,
"cus_longi" : 78.963407
},
and so on...
I want final output like this
{
"icon" : "icon path here",
"del_name" : "Boy One",
"del_lat" : 26.8808383,
"del_longi" : 75.7503407,
},
{
"icon" : "icon path here",
"cus_name" : "Roylee Wheels",
"cus_lat" : 20.594725,
"cus_longi" : 78.963407
},
and so on...
select orders_assigned.*, order.*, address.*
from orders_assigned
inner join delboy_login on delboy_login.id = orders_assigned.delboy_login
inner join `order` on `order`.`id` = orders_assigned.order_id
inner join customer_login on customer_login.cust_id = order.user_id
inner join address on address.a_id = order.address_id
where delivery_status != 'Cancelled' && order_status='Picked'
You need to join your tables. this is untested, so something like this.
It's bad practice to select * from tables, you should really be defining only the fields you need.
Also note that order is a reserved word in mysql so not a good name for a table - hence the backticks.
Try this : It will work !
SELECT oa.delivery_status, oa.username oa.order_id, dl.name, dl.lat, dl.longi, o.address_id, o,user_id, cl.name, a.lat, a.longi
FROM orders_assigned as oa
JOIN delboy_login as dl ON oa.username = dl.id
JOIN order as o ON oa.order_id = o.order_id
JOIN customer_login as cl ON = o.user_id = cl.cust_id
JOIN address as a ON = o.address_id = a.a_id
WHERE oa.delivery_status != 'Cancelled' && oa.order_status='Picked'
SELECT
orders_assigned.delivery_status AS delivery_status,
orders_assigned.username AS username,
orders_assigned.order_id AS order_id,
delboy_login.name AS del_name,
delboy_login.lat AS del_lat,
delboy_login.longi AS del_longi,
order.address_id AS address_id,
order.user_id AS user_id,
customer_login.name AS cus_name,
address.lat AS cus_lat,
address.longi AS cus_longi
FROM
orders_assigned
LEFT JOIN
delboy_login ON delboy_login.id = orders_assigned.username
LEFT JOIN
orders ON order.order_id = orders_assigned.order_id
LEFT JOIN
customer_login ON customer_login.cust_id = order.user_id
LEFT JOIN
address ON address.a_id = order.address_id
Here is the SQL you want.
Take note that you can rename the columns that the query returns as you can see from below.
delboy_login.name AS del_name,
delboy_login.lat AS del_lat,
delboy_login.longi AS del_longi,
customer_login.name AS cus_name,
address.lat AS cus_lat,
address.longi AS cus_longi
Joining table is very important, I hope that you will be able to pick up the query pattern in the future.
Best of luck to you.
EDIT:
The output you desire can be achieved by simply creating 2 different temp_arrays, and pushing them into the main array one after the other.
if ($count1 >= 1) {
while ($row = $sql->fetch()) {
$delivery_status = $row['delivery_status'];
$deliveryboy_id = $row['username'];
$order_id = $row['order_id'];
$del_name = $row['del_name'];//name
$del_lat = $row['del_lat'];//lat
$del_longi = $row['del_longi'];//long
$del_icon = $row['del_icon'];//icon
$address_id = $row['address_id'];
$user_id = $row['user_id'];
$cus_name = $row['cus_name'];//name
$cus_lat = $row['cus_lat'];//lat
$cus_longi = $row['cus_longi'];//long
$cus_icon = $row['cus_icon'];//icon
$tmp_del = array();
$tmp_del['del_lat'] = $del_lat;
$tmp_del['del_name'] = $del_name;
$tmp_del['del_longi'] = $del_longi;
$tmp_del['del_icon'] = $del_icon;
$tmp_cus = array();
$tmp_cus['cus_lat'] = $cus_lat;
$tmp_cus['cus_name'] = $cus_name;
$tmp_cus['cus_longi'] = $cus_longi;
$tmp_cus['cus_icon'] = $cus_icon;
array_push($response, $tmp_del);
array_push($response, $tmp_cus);
}

Query to Json: Return Each Column Twice with Different Names

I have this php code to get all payments (payment amount, the name of the user, the month of the payment) deposited by all users in all months:
$result = $mysqli->query("SELECT p.id as id, p.amount as amount,
u.name as user_id, m.name as month_id
FROM payment p, user u, month m
WHERE p.user_id = u.id AND p.month_id = m.id;");
//Add all records to an array
$rows = array();
while($row = $result->fetch_array())
{
$rows[] = $row;
}
//Return result
$jTableResult = array();
$jTableResult['Result'] = "OK";
$jTableResult['Records'] = $rows;
print json_encode($jTableResult);
And this is the json I get:
[{
"Result": "OK",
"Records": [
{
"0": "1",
"id": "1",
"1": "250",
"amount": "250",
"2": "user 1",
"user_id": "user 1",
"3": "jan 15",
"month_id": "jan 15"
},
...]
Now, I think these "0", "1", "2", "3" names/values are not supposed to be there and I must have done something wrong here. Is this the doing of the json_encode()? Or is it the way I'm querying the db?
Thanks for the help!
The issu here is that you are calling fetch_array().
fetch_array() will return an array of index based values as well as key based values. So if you only want the key(name) based values in the array, use the below code.
Try fetch_assoc().
$rows = array();
while($row = $result->fetch_assoc())
{
$rows[] = $row;
}
Or fetch_array(MYSQLI_ASSOC)
$rows = array();
while($row = $result->fetch_array(MYSQLI_ASSOC))
{
$rows[] = $row;
}

Categories