如何编写Mysql查询以使用JOINS获取嵌套的json数组?

时间:2018-06-15 10:52:46

标签: mysql mysqli mysql-error-1064

我处于非常困难的境地,我需要你的帮助。 我正在进行类似项目的计划,我必须以特定的json格式从mysqli数据库加载所有信息。 (否则他们无法改变它)

所以格式应该是这样的:

{  
   "data":[  
      {  
         "id_profile":"66",
         "nom":"BARRAUD ",
         "groupe":"1",
         "tasks":[  
            {  
               "id_counter":"8",
               "id_profile":"66",
               "from_interval":"1528092000",
               "to_interval":"1528138800",
               "counter":"16",
               "hrname":"EC2"
            },
            {  
               "id_counter":"458",
               "id_profile":"66",
               "from_interval":"1532412000",
               "to_interval":"1532458800",
               "counter":"16",
               "hrname":"EC1"
            },
            {  
               "id_counter":"466",
               "id_profile":"66",
               "from_interval":"1532757600",
               "to_interval":"1532804400",
               "counter":"14",
               "hrname":"EC1"
            }
         ]
      }
]}

这是他们使用的原始代码:

<?php
if(isset($_GET['counter'])){
  require_once '../functions.php';

  $sDateHour = $_GET['sDateHour'];
  $eDateHour = $_GET['eDateHour'];

  $now = time() - 24*60*60;  
  $fn= new Func;
  $fn->select('id_profile, nom, groupe','profile',''," date_f_contract>='$now' AND groupe>0 ORDER BY nom");

  $sel = new Func;
  $getHrName = new Func;

  while($row=mysqli_fetch_assoc($fn->select)){
    $pr_id=$row['id_profile'];

    $sel->select('*','counter',''," from_interval>='$sDateHour' AND to_interval<='$eDateHour' AND id_profile='$pr_id'");
    $nr= mysqli_num_rows($sel->select);



    if($nr>0){
      //here we have to do the total counter
      $totalCounter = 0;
      $from_interval=0;
      $to_interval = 0;
      $name ="";


      $tmp_id_profile = 0;
      $tmp_f_int =0;
      $tmp_to_int=0;

      while($r=mysqli_fetch_assoc($sel->select)){
        $frint = $r['from_interval'];
        $toint = $r['to_interval'];
        //
        $counter_ct = $r['counter'];

        $totalCounter+=$counter_ct;

        $getHrName->select('libelle AS lbl, COUNT(libelle) AS totalHr',"horraire",""," date_heure_deb>='$frint' AND date_heure_fin<='$toint' AND id_profile='$pr_id' GROUP BY libelle ORDER BY totalHr DESC LIMIT 1");
        $rr = mysqli_fetch_assoc($getHrName->select);
        $r['hrname']=$rr['lbl'];
        $name=$rr['lbl'];

        $r['counter']=$rr['totalHr'];


        $row['tasks'][]=$r;


      }

    }
      $res[]=$row;
  }

  $temp['data']=$res;
  $fn->deconnect();
$sel->deconnect();


  echo json_encode($temp, JSON_PRETTY_PRINT);

}

 ?>

但加载数据的时间太长了,我正在考虑使用Joins的机会?在这种情况下可以使用任何JOINS吗?这会给我一个更快的结果吗?

我一直试图将查询更改为:

SELECT pr.id_profile, pr.nom, pr.groupe, ct.* FROM profile AS pr 
INNER JOIN counter AS ct ON pr.id_profile = ct.id_profile WHERE
(ct.from_interval>='$sDateHour' AND ct.to_interval<='$eDateHour') AND
pr.date_f_contract>='$now' AND groupe>0 ORDER BY nom

你身边的任何帮助都会为我节省很多时间。 谢谢!

1 个答案:

答案 0 :(得分:0)

总的来说,是的。连接总是比单独的查询更好,更容易阅读。 下次请以更好的格式发布代码。到目前为止,这件事真的很难读。 如果我读得正确,这应该可行,即使你应该真的从mysqli切换到PDO:

SELECT
            `profile`.id_profile,
            `profile`.nom,
            `profile`.groupe,

            counter.from_interval,
            counter.to_interval,
            counter.counter,

            libelle AS lbl,
            COUNT(libelle) AS totalHr
FROM        `profile`
INNER JOIN  counter
    ON      counter.id_profile = `profile`.id_profile
INNER JOIN  horraire
    ON      horraire.id_profile = `profile`.id_profile
            AND horraire.date_heure_deb >= counter.from_interval
            AND horraire.date_heure_fin <= counter.to_interval
WHERE       `profile`.date_f_contract >= CURDATE() AND `profile`.groupe > 0
            AND from_interval >= '$sDateHour' AND to_interval <= '$eDateHour'
GROUP BY    libelle
ORDER BY    totalHr DESC;

然后你可以用PHP完成剩下的工作(如果你使用的是MySQL +5.7或MariaDB 10.3),你可以使用数据库本身的JSON函数。