如何简化图表数据的mysqli查询?

时间:2017-05-19 15:03:22

标签: php mysqli

所以我试图找到一种方法来最小化这段代码。在顶部我得到当年。

//Get the current year
$theYear = date("Y", strtotime($day));
    if(isset($_POST['theYear'])){
        $theYear = $_POST['year_select'];
}

进一步下来我得到了一年中每周的小时数。我的代码有53个星期,但我刚刚抓了10个参考。它的设置如下。

$week01 = mysqli_query($con, "SELECT SUM(hours) AS tHours01 FROM timecard WHERE YEARWEEK(date, 1) = '".$theYear."01'");
$week02 = mysqli_query($con, "SELECT SUM(hours) AS tHours02 FROM timecard WHERE YEARWEEK(date, 1) = '".$theYear."02'");
$week03 = mysqli_query($con, "SELECT SUM(hours) AS tHours03 FROM timecard WHERE YEARWEEK(date, 1) = '".$theYear."03'");
$week04 = mysqli_query($con, "SELECT SUM(hours) AS tHours04 FROM timecard WHERE YEARWEEK(date, 1) = '".$theYear."04'");
$week05 = mysqli_query($con, "SELECT SUM(hours) AS tHours05 FROM timecard WHERE YEARWEEK(date, 1) = '".$theYear."05'");
$week06 = mysqli_query($con, "SELECT SUM(hours) AS tHours06 FROM timecard WHERE YEARWEEK(date, 1) = '".$theYear."06'");
$week07 = mysqli_query($con, "SELECT SUM(hours) AS tHours07 FROM timecard WHERE YEARWEEK(date, 1) = '".$theYear."07'");
$week08 = mysqli_query($con, "SELECT SUM(hours) AS tHours08 FROM timecard WHERE YEARWEEK(date, 1) = '".$theYear."08'");
$week09 = mysqli_query($con, "SELECT SUM(hours) AS tHours09 FROM timecard WHERE YEARWEEK(date, 1) = '".$theYear."09'");
$week10 = mysqli_query($con, "SELECT SUM(hours) AS tHours10 FROM timecard WHERE YEARWEEK(date, 1) = '".$theYear."10'");

我尝试做一个while循环,但发现它是太多的PHP层才能正常工作。所以我回复了一个while循环,给我下面的查询,然后将其粘贴到我的代码中。

在上面的代码下面,我也抓取了所有数据,并使用与上面相同的方法重复代码输出。

$Total01 = mysqli_fetch_object($week01);
$Total02 = mysqli_fetch_object($week02);
$Total03 = mysqli_fetch_object($week03);
$Total04 = mysqli_fetch_object($week04);
$Total05 = mysqli_fetch_object($week05);
$Total06 = mysqli_fetch_object($week06);
$Total07 = mysqli_fetch_object($week07);
$Total08 = mysqli_fetch_object($week08);
$Total09 = mysqli_fetch_object($week09);
$Total10 = mysqli_fetch_object($week10);

然后,所有这些数据都会回显到表格中的单元格中,然后转换为图形,但前提是本周有几个小时。因此,图表会随着我们记录未来几周的时间而增长,而不是在年初的右边有一个大的空白区域,并慢慢填充它。

<? if(($Total01->tHours01) > 0) { ?><td><? if(empty($Total01->tHours01)){echo '0';}else{ echo $Total01->tHours01;}?></td><? } ?>
<? if(($Total02->tHours02) > 0) { ?><td><? if(empty($Total02->tHours02)){echo '0';}else{ echo $Total02->tHours02;}?></td><? } ?>
<? if(($Total03->tHours03) > 0) { ?><td><? if(empty($Total03->tHours03)){echo '0';}else{ echo $Total03->tHours03;}?></td><? } ?>
<? if(($Total04->tHours04) > 0) { ?><td><? if(empty($Total04->tHours04)){echo '0';}else{ echo $Total04->tHours04;}?></td><? } ?>
<? if(($Total05->tHours05) > 0) { ?><td><? if(empty($Total05->tHours05)){echo '0';}else{ echo $Total05->tHours05;}?></td><? } ?>
<? if(($Total06->tHours06) > 0) { ?><td><? if(empty($Total06->tHours06)){echo '0';}else{ echo $Total06->tHours06;}?></td><? } ?>
<? if(($Total07->tHours07) > 0) { ?><td><? if(empty($Total07->tHours07)){echo '0';}else{ echo $Total07->tHours07;}?></td><? } ?>
<? if(($Total08->tHours08) > 0) { ?><td><? if(empty($Total08->tHours08)){echo '0';}else{ echo $Total08->tHours08;}?></td><? } ?>
<? if(($Total09->tHours09) > 0) { ?><td><? if(empty($Total09->tHours09)){echo '0';}else{ echo $Total09->tHours09;}?></td><? } ?>
<? if(($Total10->tHours10) > 0) { ?><td><? if(empty($Total10->tHours10)){echo '0';}else{ echo $Total10->tHours10;}?></td><? } ?>

所有这一切都很好,花花公子,但我很好奇,如果有办法做到这一点,我不知道?

1 个答案:

答案 0 :(得分:0)

为了减少对数据库的请求量,您可以创建更复杂的查询,这将获取所需的所有数据,然后正确呈现它。

考虑到图表数据必须是连续的,需要存在所有可能的周值 为了生成连续数序列,可以选择多种方法。其中一些需要新表生成,而其他人可以生成序列而无需直接表操作。 This answer帮助完成此任务。

所以,让我们选择要显示的周数范围。它可以很容易地从1到53或其他东西。对于查询示例,请将它们设置为 20到35 ,这些周的基本值将为0小时。

# SEQUENCE OF WEEK NUMBERS NEEDED
SELECT (SELECT 0) AS tHours, (t*10+u+1) AS tWeek FROM
(SELECT 0 t UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) A,
(SELECT 0 u UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) B
HAVING tWeek BETWEEN 20 AND 35;

此外,我们还需要获取有关每周实际工作时数的数据 这可以通过以下查询轻松完成:

# WEEKLY HOURS;
SELECT SUM(hours) AS tHours, WEEK(date, 1) AS tWeek
FROM timecard
WHERE YEARWEEK(date, 1) BETWEEN 200920 AND 200935
GROUP BY YEARWEEK(date, 1);

因此,为了获得所需的所有数据,我们可以组合以前的查询,它们将类似于以下示例:

# RESULT QUERY
SELECT SUM(tHours) AS tHours, tWeek 
FROM 
    ((SELECT SUM(hours) AS tHours, WEEK(date, 1) AS tWeek
        FROM timecard
        WHERE YEARWEEK(date, 1) BETWEEN 200920 AND 200935
        GROUP BY YEARWEEK(date, 1))
    UNION
    (SELECT (SELECT 0) AS tHours, (t*10+u+1) AS tWeek FROM
        (SELECT 0 t UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
        SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) A,
        (SELECT 0 u UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
        SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) B
        HAVING tWeek BETWEEN 20 AND 35
    ORDER BY tWeek)) data
GROUP BY tWeek;

这些带有结果输出的示例提供了here

下一步是从脚本执行此查询并呈现结果 我有一段时间没有使用过PHP,如果代码混乱,那就很抱歉。我将尝试编写示例代码,以向您展示如何使用结果进行操作。

我们假设您已经有$theYear个变量 下一步是选择要显示的周数范围。

$startWeek = 20;
$endWeek = 35;

查询对象将是这样的:

$query = "SELECT SUM(tHours) AS tHours, tWeek ".
"FROM ". 
    "((SELECT SUM(hours) AS tHours, WEEK(date, 1) AS tWeek ".
        "FROM timecard ".
        "WHERE YEARWEEK(date, 1) BETWEEN ".
        $theYear.$startWeek." AND ".
        $theYear.$endWeek." ".
        "GROUP BY YEARWEEK(date, 1)) ".
    "UNION ".
    "(SELECT (SELECT 0) AS tHours, (t*10+u+1) AS tWeek FROM ".
        "(SELECT 0 t UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION ".
        "SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) A, ".
        "(SELECT 0 u UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION ".
        "SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) B ".
        "HAVING tWeek BETWEEN ".$startWeek." AND ".$endWeek." ".
    "ORDER BY tWeek)) data ".
"GROUP BY tWeek";

下一个逻辑步骤是从数据库中获取数据:

$weeks = mysqli_query($con, $query);

我们需要最后渲染结果,这可以通过多种方式完成,例如:

while ($row = mysqli_fetch_array($weeks, MYSQLI_ASSOC)) {
    $result = "<td>".$row['tHours']."</td>"; // $row['tWeek'] also can be rendered
    echo $result;
}

因此,这种方法可以大大减少数据库请求的数量并提高整体性能,并缩短应用程序的响应时间。此外,周数的范围可以通过改变相应的变量而变化 尽管SQL请求变得更加复杂,但代码对不需要的变量的污染较少。

这段代码可以用多种方式编写,可能还有进一步改进的地方。所以我只是分享了我的观点,你的观点也不同。

感谢您的阅读。