简体   繁体   中英

Group json data with common fields on php

I get my data in a json format after I execute an sql query(MYSQL) to the server and I would like somehow to group the data regarding the fields with common name.This is the code I handle the data and my result after the execution of the query.

<?php

$serverName = "localhost";
$userName = "root";
$password = "root";
$database = "eshop";

// Create connection with the database
$conn = new mysqli($serverName, $userName, $password , $database);

//Retrieves the two values sent from the ajax request
$userName = $_GET["userName"];

// Check the status of the connection
if ($conn->connect_error)
{
    alert("The connection has timed-out!!!");
    die("Connection failed: " . $conn->connect_error);

}

else
{
    $data = new stdclass();
    $data->status = "";
    $past_orders = [];

    $previous_orders_sql =  mysqli_query($conn , 
     "SELECT order_products.order_id , order_date , product_id , price
      FROM   register , orders , order_products , products
      WHERE  register.user_id = orders.user_id
      AND    orders.order_id  = order_products.order_id
      AND    products.product_id = order_products.product_num
      AND    user_name = '$userName'");


    if(mysqli_num_rows($previous_orders_sql)>0)
    {

        $data->status = "OK";

        while($row = mysqli_fetch_array( $previous_orders_sql , MYSQLI_ASSOC))
        {
            $data-> past_orders[] = $row;
        }

    }

    else
    {
        $data->status = "Failed";
        mysqli_error($conn);
    }

}

echo json_encode($data);

?>

The results that I get:

{"past_orders":
[{"order_id":"1","order_date":"2012-12-27","product_id":"1","price":"12.40"},{"order_id":"1","order_date":"2012-12-27","product_id":"2","price":"32.00"},{"order_id":"1","order_date":"2012-12-27","product_id":"3","price":"25.00"},{"order_id":"3","order_date":"2016-01-12","product_id":"1","price":"12.40"},{"order_id":"3","order_date":"2016-01-12","product_id":"6","price":"28.00"},{"order_id":"3","order_date":"2016-01-12","product_id":"7","price":"37.00"},{"order_id":"4","order_date":"2014-04-06","product_id":"1","price":"12.40"},{"order_id":"4","order_date":"2014-04-06","product_id":"2","price":"32.00"},{"order_id":"4","order_date":"2014-04-06","product_id":"5","price":"13.50"}]}

So I would like to have something that will group the data regarding the order_id (as order_id and order_date are the same for some of the results) and have something like:

{"past_orders":

[{"order_id":"1","order_date":"2012-12-27", "products":["product_id":"1","price":"12.40"},"product_id":"2","price":"32.00"},"product_id":"3","price":"25.00"}],

{"order_id":"3","order_date":"2016-01-12","products":["product_id":"1","price":"12.40"},{"product_id":"6","price":"28.00"},{"product_id":"7","price":"37.00"}],

{"order_id":"4","order_date":"2014-04-06","products":["product_id":"1","price":"12.40"},{"product_id":"2","price":"32.00"},{"product_id":"5","price":"13.50"}]}

If any extra code required for the answers please let me know to post it.

I would redo your while iteration in this manner:

    while ($row = mysqli_fetch_array($previous_orders_sql, MYSQLI_ASSOC)) {

        if (!isset($data->past_orders[$row['order_id']])) {
            $order_arr = array(
                "order_id" => $row['order_id'],
                "order_date" => $row['order_date']
            );
            $data->past_orders[$row['order_id']] = $order_arr;
        }

        $data->past_orders[$order['order_id']]['products'][] = array(
            "product_id" => $row['product_id'],
            "price" => $row['price']
        );
    }

That way your results are in a nice set as such:

array (size=3)
  0 => 
    array (size=3)
      'order_id' => int 1
      'order_date' => string '2012-12-27' (length=10)
      'products' => 
        array (size=3)
          0 => 
            array (size=2)
              'product_id' => int 1
              'price' => float 12.4
          1 => 
            array (size=2)
              'product_id' => int 2
              'price' => float 32
          2 => 
            array (size=2)
              'product_id' => int 3
              'price' => float 25
  1 => 
    array (size=3)
      'order_id' => int 3
      'order_date' => string '2016-01-12' (length=10)
      'products' => 
        array (size=2)
          0 => 
            array (size=2)
              'product_id' => int 1
              'price' => float 12.4
          1 => 
            array (size=2)
              'product_id' => int 6
              'price' => float 28
  2 => 
    array (size=3)
      'order_id' => int 4
      'order_date' => string '2014-04-06' (length=10)
      'products' => 
        array (size=3)
          0 => 
            array (size=2)
              'product_id' => int 1
              'price' => float 12.4
          1 => 
            array (size=2)
              'product_id' => int 2
              'price' => float 32
          2 => 
            array (size=2)
              'product_id' => int 5
              'price' => float 13.5

Also, your SQL query is not efficient. You should use JOINs instead:

SELECT o.order_id, o.order_date, p.product_id, p.price
FROM orders as o 
JOIN register as r ON r.user_id=o.user_id
JOIN order_products as op ON op.order_id=o.order_id
JOIN products as p ON p.product_id=op.product_num
WHERE r.username = '$userName'

I understand that you want to re-structure this data structure so that it's easier to work with it. The simple version could be this:

    while($row = mysqli_fetch_array( $previous_orders_sql , MYSQLI_ASSOC))
    {
        if(!isset($data->past_orders[$row['order_id']]))
          $data->past_orders[$row['order_id']] = array();
        }

        $data->past_orders[$row['order_id']][] = $row;
    }

You can further massage this array to get exactly what you need, if that's really necessary.

Put another line in the query that orders by ID and then in the where statement put an internal where. Like this:

 $previous_orders_sql =  mysqli_query($conn , 
 "SELECT order_products.order_id , order_date , product_id , price
  FROM   register , orders , order_products , products
  WHERE  register.user_id = orders.user_id
  AND    orders.order_id  = order_products.order_id
  AND    products.product_id = order_products.product_num
  AND    user_name = '$userName'
  order by orders.order_id desc");


if(mysqli_num_rows($previous_orders_sql)>0)
{

    $data->status = "OK";

    while($row = mysqli_fetch_array( $previous_orders_sql , MYSQLI_ASSOC))
    {
        $idvar = $row[order_id];

        while($row = mysqli_fetch_array( $previous_orders_sql , MYSQLI_ASSOC))
            {
             if ($row[order_id] == $idvar)
             $data-> past_orders[] = $row[order_date].$row[product_id].$row[price] etc etc etc;
            }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM