我处于非常困难的境地,我需要你的帮助。 我正在进行类似项目的计划,我必须以特定的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
你身边的任何帮助都会为我节省很多时间。 谢谢!
答案 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函数。