【发布时间】:2021-01-16 06:54:51
【问题描述】:
我有 PHP 代码从 CSV 文件中读取数据以填充到 HTML 表中。正在读取的 CSV 文件如下所示(示例;不是整个文件):
A,2020-06-01,1,15,0,0,99.5,problem,
B,2020-06-01,0,0,0,0,100,,
A,2020-06-02,0,0,0,0,100,,
B,2020-06-02,0,0,0,0,100,,
A,2020-06-03,0,0,0,0,100,,
B,2020-06-03,0,0,1,30,99.2,problem,
A,2020-06-04,0,0,0,0,100,,
B,2020-06-04,0,0,0,0,100,,
A,2020-06-05,0,0,0,0,100,,
B,2020-06-05,0,0,1,10,99.7,problem,
A,2020-06-06,0,0,0,0,100,,
B,2020-06-06,0,0,0,0,100,,
A,2020-06-07,0,0,0,0,100,,
B,2020-06-07,0,0,0,0,100,,
A,2020-06-08,1,60,0,0,98.9,problem,
B,2020-06-08,0,0,0,0,100,,
服务“A”和“B”每天记录价值。
用于处理 CSV 文件的代码如下所示:
<?php
$filename = "/var/tmp/dataset.csv";
if (($h = fopen($filename, "r")) !== FALSE)
{
$A_totals = array();
$B_totals = array();
$cols = array();
$A_index = 1;
$B_index = 1;
$cols = array("service_name", "date", "nbr_out", "hrs_out", "nbr_dgrd", "hrs_dgrd", "pct_avail", "comments");
// Loop through rows in CSV file
while (($row = fgetcsv($h, 10000, ",")) !== FALSE) {
// Assign variables and create summary arrays for each service
$recordYear = strpos($row[1], $searchYear.'-');
$recordMonth = strpos($row[1], '-'.$searchMonth.'-');
if ($recordYear !== FALSE && $recordMonth !== FALSE) {
if ($row[0] == 'A') {
$A_totals['item_' . $A_index++] = array_combine($cols, $row);
}
if ($row[0] == 'B') {
$B_totals['item_' . $B_index++] = array_combine($cols, $row);
}
}
}
$A_nbr_out_totals = array_sum(array_column($A_totals, 'nbr_out'));
$A_hrs_out_totals = array_sum(array_column($A_totals, 'hrs_out'));
$A_nbr_dgrd_totals = array_sum(array_column($A_totals, 'nbr_dgrd'));
$A_hrs_dgrd_totals = array_sum(array_column($A_totals, 'hrs_dgrd'));
$A_pct_avail_totals = array_sum(array_column($A_totals, 'pct_avail'));
$A_pct_avail_total_count = count(array_column($A_totals, 'pct_avail'));
$A_pct_avail_avg = round(( $A_pct_avail_totals / $A_pct_avail_total_count ), 4 );
$B_nbr_out_totals = array_sum(array_column($B_totals, 'nbr_out'));
$B_hrs_out_totals = array_sum(array_column($B_totals, 'hrs_out'));
$B_nbr_dgrd_totals = array_sum(array_column($B_totals, 'nbr_dgrd'));
$B_hrs_dgrd_totals = array_sum(array_column($B_totals, 'hrs_dgrd'));
$B_pct_avail_totals = array_sum(array_column($B_totals, 'pct_avail'));
$B_pct_avail_total_count = count(array_column($B_totals, 'pct_avail'));
$B_pct_avail_avg = round(( $B_pct_avail_totals / $B_pct_avail_total_count ), 4 );
}
代码读取 CSV 文件,并为给定月份/年份的 CSV 文件中的每个数字“列”提供服务总计。然后将这些总数传递到 HTML 表中以供服务显示。
我已以“对等”方式将 CSV 数据导出到 Oracle 表中。表中使用的列名与 CSV 文件使用的名称相似,不同之处在于每个 Oracle 表列的开头都添加了“IA_”前缀。
我的挑战:现在我使用 Oracle 表来引用数据,我在 PHP 代码中根据需要使用 OCI8。如果可能的话,我想保持 PHP 数组方法完整(据我所知它有效)。 OCI8 代码会读取 Oracle 表的每一行并将其添加到数组中以供其他数组命令 (array_combine/array_sum/array_map) 使用。
在尝试此操作时,我已将代码修改为如下所示:
<?php
$A_totals = array();
$B_totals = array();
$cols = array();
$A_index = 1;
$B_index = 1;
$cols = array("service_name", "date", "nbr_out", "hrs_out", "nbr_dgrd", "hrs_dgrd", "pct_avail", "comments");
$sql1 = "SELECT IA_SERVICE, TO_CHAR(IA_DATE, 'MM/DD/YYYY HH12:MI:SS AM') AS IA_DATE, IA_NBR_OUT, IA_HRS_OUT, IA_NBR_DGRD, IA_HRS_DGRD, IA_PCT_AVAIL, IA_COMMENTS FROM i_avail WHERE TO_CHAR(IA_DATE, 'Mon')='$searchMonth' AND TO_CHAR(IA_DATE, 'YYYY')='$searchYear'";
$stid1 = oci_parse($connect, $sql1);
$r = oci_execute($stid1);
// Loop through rows in Oracle table
while (($row = oci_fetch_array($stid1, OCI_BOTH+OCI_RETURN_LOBS))!= false) {
// Assign variables and create summary arrays for each service
if ($row['IA_SERVICE'] == 'A') {
$A_totals['item_' . $A_index++] = array_combine($cols, $row);
}
if ($row['IA_SERVICE'] == 'B') {
$B_totals['item_' . $B_index++] = array_combine($cols, $row);
}
}
$A_nbr_out_totals = array_sum(array_column($A_totals, 'nbr_out'));
$A_hrs_out_totals = array_sum(array_column($A_totals, 'hrs_out'));
$A_nbr_dgrd_totals = array_sum(array_column($A_totals, 'nbr_dgrd'));
$A_hrs_dgrd_totals = array_sum(array_column($A_totals, 'hrs_dgrd'));
$A_pct_avail_totals = array_sum(array_column($A_totals, 'pct_avail'));
$A_pct_avail_total_count = count(array_column($A_totals, 'pct_avail'));
$A_pct_avail_avg = round(( $A_pct_avail_totals / $A_pct_avail_total_count ), 4 );
$B_nbr_out_totals = array_sum(array_column($B_totals, 'nbr_out'));
$B_hrs_out_totals = array_sum(array_column($B_totals, 'hrs_out'));
$B_nbr_dgrd_totals = array_sum(array_column($B_totals, 'nbr_dgrd'));
$B_hrs_dgrd_totals = array_sum(array_column($B_totals, 'hrs_dgrd'));
$B_pct_avail_totals = array_sum(array_column($B_totals, 'pct_avail'));
$B_pct_avail_total_count = count(array_column($B_totals, 'pct_avail'));
$B_pct_avail_avg = round(( $B_pct_avail_totals / $B_pct_avail_total_count ), 4 );
我这次尝试的结果反映了每个定义的值都为零,这不是预期的。
由于数据现在在 Oracle 中,我可能会为每个利用 COUNT 和 AVG 函数的变量添加额外的 SQL 语句……但这将是很多语句。如果将来增加额外的服务,SQL 语句的数量会相应增加。如果可能的话,我想避免这种情况……因此我希望我可以利用已经存在的代码。
这可能吗?如果没有,我可以尝试另一种不需要大量 SQL 语句的方法吗?
【问题讨论】: