按 JSON 数组对 SQL 数据进行分组

Posted

技术标签:

【中文标题】按 JSON 数组对 SQL 数据进行分组【英文标题】:Group SQL data by JSON arrays 【发布时间】:2016-02-17 12:30:19 【问题描述】:

我正在为教师制作一个显示学生考试成绩的页面。

要显示图表,我想使用Highcharts javascript 库。

到目前为止,我有一个 php 脚本,它使用 PDO 创建 JSON 数据,以后可以从不同的页面将其提供给 Highcharts

我的问题: 如何将来自同一 student 的所有数据分组到一个数组中?请参阅最后一个示例了解我希望实现的目标。另外:我希望将所有数据包含在一个总体 JSON 数组中。

我想要这个:

[
  "student": "Andreas",
  "level" : [4, 3]
, 
  "student": "Eivind",
  "level" : [4, 5]
, 
  "student": "Ole",
  "level" : [4, 3]
]

这是我的 PHP 的样子:

<?php

require("config.inc.php");

$school = $_GET["school"];
$class = $_GET["class"];

//initial query
$query = 'SELECT student, taskid, level FROM task
            WHERE school=' . '"' . $school . '"' .  ' AND class=' . '"' . $class . '" ORDER BY student';

//execute query
try 
    $stmt   = $db->prepare($query);
    $result = $stmt->execute();

catch (PDOException $ex) 
    $response["success"] = 0;
    $response["message"] = "Database Error!";
    die(json_encode($response));


// Finally, we can retrieve all of the found rows into an array using fetchAll 
$rows = $stmt->fetchAll();

if ($rows) 
    $response["posts"]   = array();

    foreach ($rows as $row) 
        $post               = array();
        $post["student"]       = $row["student"];
        $post["level"]         = $row["level"];


        //update our repsonse JSON data
        array_push($response["posts"], $post);
    

    // echoing JSON response
    echo json_encode($response, JSON_NUMERIC_CHECK);


 else 
    $response["success"] = 0;
    $response["message"] = "No Post Available!";
    die(json_encode($response));


?>

这是我从 PHP 中得到的:


  "posts": [
    
      "student": "Andreas",
      "level": 4
    ,
    
      "student": "Andreas",
      "level": 3
    ,
    
      "student": "Eivind",
      "level": 4
    ,
    
      "student": "Eivind",
      "level": 5
    ,
    
      "student": "Ole",
      "level": 4
    ,
    
      "student": "Ole",
      "level": 3
    
  ]

【问题讨论】:

【参考方案1】:

您可以通过将学生姓名用作数组键来非常轻松地构建这样的数组。构建数组后,您可以使用array_values 将字符串键转换回数字键。

...
if ($rows) 
    foreach ($rows as $row) 
        $posts[$row['student']]['student'] = $row['student'];
        $posts[$row['student']]['level'][] = $row['level'];
    
    $response = array_values($posts);

    echo json_encode($response, JSON_NUMERIC_CHECK);

 else  ...

这应该会给你以下$response

[
  
    "student": "Andreas",
    "level": [4, 3]
  ,
  
    "student": "Eivind",
    "level": [4, 5]
  ,
  
    "student": "Ole",
    "level": [4, 3]
  
]

【讨论】:

这太棒了!谢谢。【参考方案2】:

在 php 中你可以这样做:

在你的 foreach 中

foreach ($rows as $row) 
    $post               = array();
    $post["student"]       = $row["student"];
    $post["level"]         = $row["level"];


    //update our repsonse JSON data
    array_push($response["posts"], $post);

你需要做这样的事情:

<?php
$response = array();
$response["posts"]   = array();

$students = array("student1", "student2", "student3", "student1");

$tempArray = array();

foreach ($students as $student) 
    $lvl        = 1;
    if(!isset($tempArray[$student]))
              $tempArray[$student] =  array("name" => $student, "level" => array($lvl));
    
    else
        $tempArray[$student]["level"][] = $lvl;
    

    // add it to the array
   $response["posts"] = $tempArray;

   // encode array
   $response = json_encode($response);

   echo "<br><br><br> ";

// example

// decode and make it a array for easier looping.
$response = (array)json_decode($response);
$responsePosts = (array) $response["posts"];

// foreach post
foreach($response["posts"] as $keyP => $valueP)

        // convert to array same as above
        $valueP = (array) $valueP;


        // key that is kinda useless but made it the student name so i can easily see if it already exists
        echo "key :".$keyP." <br />";

        // name of the student
        echo "name :".$valueP["name"]." <br />";

        // all the levels
        echo "levels: ";
        foreach($valueP["level"] as $lvl)
            echo $lvl." ";
        

        echo "<br /><br />";



?>

这应该可行。 Atm 我使用学生姓名作为键来查看它是否已经存在,否则您需要遍历所有数组并最有可能执行“name”=== $student。

不需要推送。

【讨论】:

谢谢!我在foreach 的末尾添加了array_push($response["posts"], $tempArray);,这就是我得到的:pastebin.com/n2spXp8H 关闭,但还没有。如果我在foreach 的末尾不做array_push,JSON 数据返回者为空。 我会看看我是否可以在我的示例中包含推送并使其与您的要求相同。如果可以的话,我推荐@Prashant 给出的答案。 应该这样做。要获得您想要的精确数组,您可以执行 var_dump($response["posts"][0]);数组推送创建了一个我现在不知道如何删除的密钥 0。 好吧,我有点傻。我删除了 array_push 并为其分配了数组。这应该正是您要寻找的。​​span> 你在最后几次编辑中迷失了我。''$students'' 需要硬编码,所以当这些是由实际学生生成的时候就没用了。 :-( 另外,在你的最新方法中,我没有得到 JSON 编码的数据,只有一些 PHP 转储。谢谢你的努力,但到目前为止,编辑 #2 似乎最接近。【参考方案3】:
var data=[ 
  "category" : "Search Engines", "hits" : 5, "bytes" : 50189 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 17308 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 47412 ,
  "category" : "Search Engines", "hits" : 1, "bytes" : 7601 ,
  "category" : "Business", "hits" : 1, "bytes" : 2847 ,
  "category" : "Content Server", "hits" : 1, "bytes" : 24210 ,
  "category" : "Internet Services", "hits" : 1, "bytes" : 3690 ,
  "category" : "Search Engines", "hits" : 6, "bytes" : 613036 ,
  "category" : "Search Engines", "hits" : 1, "bytes" : 2858  
];

var res = alasql('SELECT category, sum(hits) AS hits, sum(bytes) as bytes \
FROM ? \
GROUP BY category \
ORDER BY bytes DESC',[data]);

你会得到如下输出:

["category":"Search Engines","hits":13,"bytes":673684,
 "category":"Content Server","hits":3,"bytes":88930,
 "category":"Internet Services","hits":1,"bytes":3690,
 "category":"Business","hits":1,"bytes":2847]

【讨论】:

以上是关于按 JSON 数组对 SQL 数据进行分组的主要内容,如果未能解决你的问题,请参考以下文章

如何根据相同的值对数组进行分组

如何按特定的子数组值对多维数组进行分组?

java8 stream对数组按条件进行分组

如何对 json 数组进行分组并每周汇总其总数?

按不同的 id 对项目数组进行分组

按id typescript对对象数组进行分组[重复]