1

我正在为我的 SaaS 构建一个自定义报告模块,并且需要关于我正在构建的查询(MySQL 和 PHP)的一些建议。我正在动态构建一个表,返回的每条记录都将是该表上的一行。它动态地连接了许多不同的表,除了我需要加入的 3 个表之外,它都运行良好。

所有其他表都是 1-1 LEFT JOIN。例如,如果我正在查询员工表并试图找到部门 ID,它只会加入 hunky dory。它会像这样加入:

First | Last  | Dept
John  | Smith | Toy Department

让这件事变得复杂的是那些额外的 3 个表有一个 1-many 连接。还需要指出的是,当我进行此连接时,它可能会提取 2-50 行数据中的任何位置,这可能也很重要。例如,如果我正在查询员工表并需要加入时钟输入/输出表,它最终看起来像这样:

First | Last  | Time
John  | Smith | 8:00 am
John  | Smith | 12:00 pm
John  | Smith | 1:00 pm
John  | Smith | 5:00 pm

如果我进行了正确的连接,名字/姓氏将为空,但我仍然会有多行。

我想将它们保留在一行中的原因是因为在拉取报告时我正在设置的表格,当它遇到需要使用 3 个 1-many 表格之一的表格时,它需要保留在同一个数据单元中(这是我无法控制的,它必须发生):

<table>
    <tr>
        <td>John</td>
        <td>Smith</td>
        <td>8:00 am<br />12:00 pm<br />..... </td>
    </tr>
</table>

我真的真的很想避免必须点击该单元格然后运行另一个查询来提取所有数据。原因是我可以运行包含 25 列以上的数千行的报告,并且它会运行 25x1000 行的相同查询。

当数据返回时,我希望是这样的:

First | Last  | Time_1  | Time_2   | Time_3  | Time_4
John  | Smith | 8:00 am | 12:00 pm | 1:00 pm | 5:00 pm

我的一些想法是在 PHP 中运行一个 while 循环并动态构建 MySQL 的联接,但我遇到了一个问题,即我需要提供加入表的次数才能使该列正确. 我可以在技术上做到:

for($i = 1; $i < 50; ++$i) {
    $sql_fields .= "time_clock_{$i}.time AS Time_{$i},";
    $joins .= "LEFT JOIN time_clock AS time_clock_{$i} ON time_clock_{$i}.employee_id = emp.id";
}
$sql_fields = rtrim($sql_fields,',');

mysql_query("SELECT emp.field_blah, emp.field_blah2, {$sql_fields} FROM employees AS emp {$joins} WHERE condition = blah");

我只是担心这真的会导致 MySQL 的一些性能问题以及我在那里的所有疯狂连接。有人有更好的主意吗?在这一点上,我会招待任何事情。

4

2 回答 2

1

不。

构建两个查询。一个以所有1:1的元素拉动所有的人;然后另一个拉你所有的时间。然后在 PHP 中循环遍历时间,将它们填充到人们的时间数组中。

于 2012-05-10T22:25:57.483 回答
0
<?php
    $query = mysql_query("SELECT .... FROM employees LEFT JOIN.... LEFT JOIN..."); //even include the one-many tables
    $i = 0;
    while($rs = mysql_fetch_array($query)) { //note I'm using array not assoc
        // echo the 1:1 table data
        // when I hit the 1:many field do something like this, yes $j will get reset when the pointer hits the next row....I need more time to think....
        $j = 1;
        while($j) {
            if($rs[$i + $j]['id'] == $rs[$i]['id']) {
                echo $rs[$i + $j]['Time'];
                ++$skip_fields;
            } else {
                $j = 0;
            }
            ++$j;
        }
        // then use $skip_fields to skip $j number of rows that the duplicate employee ids are on and decrement the value as the pointer moves on.
        ++$i;
    }
?>

没关系......使用数值只击中列而不是行......哦,好吧。:)

于 2012-05-10T22:47:53.840 回答