我有以下PHP代码,我打算用它创建一封HTML电子邮件,它应该输出所有模型的详细信息,到期日在2个设定日期之间:
$sql = 'SELECT
GROUP_CONCAT(op.products_model),
GROUP_CONCAT(products.products_warranty_default),
GROUP_CONCAT(orders.date_purchased),
orders.customers_name
FROM orders_products op
INNER JOIN products
ON op.products_id = products.products_id
INNER JOIN orders
ON op.orders_id = orders.orders_id
INNER JOIN customers
ON orders.customers_id = customers.customers_id
GROUP BY op.orders_id';
$result = mysql_query($sql, $connection);
while ($data = mysql_fetch_row($result)) {
$models = explode(",",$data[0]); // create array from all models in the GROUP_CONCAT
$years = explode(",",$data[1]); // create array from all years in the GROUP_CONCAT
$dates = explode(",",$data[2]); // create array from all dates in the GROUP_CONCAT
$name = $data[3];
echo $header; // header of email (only the name changes on each loop)
foreach ($models as $index => $model) {
echo '
<tr>
<td width="149">
<center>'.$model.'</center>
</td>
<td width="149">
<center>'.date('d/m/Y', strtotime('+'.$years[$index].' years', strtotime($dates[$index]))).'</center>
</td>
</tr>'; // echos the model in first column and date+years in second column
}
echo $footer; // static HTML again like the header
}
我一直在思考的是,如果表中存在日期在两个日期之间的模型,即2014年5月1日至5月31日,如何仅输出页眉、表和页脚的组合。它当前正在输出所有日期。
我试过各种方法来做到这一点,但在大约6个小时的失败后,我准备把我的电脑扔出窗外。我只有几周的PHP经验(以及编程经验),所以它可能(希望)是一个我不知道的简单修复。
注意:我应该注意的是,对于我用来测试的当前数据库,我可以修改选择查询以输出相关日期,但在我使用的实际数据库(我只能在工作中访问该数据库)上没有保修字段,我必须通过php从产品的长描述中提取信息,并将其输入到一个函数中。
最终代码:
$sql = 'SELECT op.products_model,
products.products_warranty_default,
orders.date_purchased,
orders.customers_name
FROM orders_products op
INNER JOIN products ON op.products_id = products.products_id
INNER JOIN orders ON op.orders_id = orders.orders_id
INNER JOIN customers ON orders.customers_id = customers.customers_id
ORDER BY orders.customers_name, op.orders_id,
op.products_model,
products.products_warranty_default,
orders.date_purchased';
$result = mysql_query($sql, $connection);
$previous_name = "";
while ($data = mysql_fetch_row($result)) {
$model = $data[0];
$year = $data[1];
$date = $data[2];
$name = $data[3];
$expiry = strtotime('+'.$year.' years', strtotime($date));
if ($previous_name != $name && $expiry >= strtotime('2014-05-01') && $expiry <= strtotime('2014-05-31')) { // on a new customer name ...
if ($previous_name != "") {
// if there is a previous customer, write the footer
echo $footer;
$previous_name = $name;
}
}
if ($expiry >= strtotime('2014-05-01') && $expiry <= strtotime('2014-05-31')){
echo '
<tr>
<td width="149">
<center>'.$model.'</center>
</td>
<td width="149">
<center>'.date('d/m/Y', $expiry).'</center>
</td>
</tr>'; // echos the model in first column and date+years in second column
}
}
if ( $previous_name != "" && $expiry >= strtotime('2014-05-01') && $expiry <= strtotime('2014-05-31')) {
echo $footer;
}
在SQL查询中聚合了很多东西,然后在PHP中对其进行分解,这似乎有点奇怪。我相信,这会让你很难匹配日期。
你可以尝试这个非聚合查询:
SELECT op.products_model,
products.products_warranty_default,
orders.date_purchased,
orders.customers_name
FROM orders_products op
INNER JOIN products ON op.products_id = products.products_id
INNER JOIN orders ON op.orders_id = orders.orders_id
INNER JOIN customers ON orders.customers_id = customers.customers_id
WHERE orders.date_purchased >= DATE('2014-05-01')
AND orders.date_purchased < DATE('2014-05-31') + INTERVAL 1 DAY
ORDER BY orders.customer_name, op.orders_id,
op.products_model,
products.products_warranty_default,
orders.date_purchased,
这将返回与日期范围匹配的详细记录。
我认为,用php处理结果集非常容易。您需要检测客户名称的更改才能输出页眉和页脚。这就是$previous_name的意义所在。
$previous_name = "";
while ($data = mysql_fetch_row($result)) {
$model = $data[0];
$year = $data[1];
$date = $data[2];
$name = $data[3];
if ($previous_name != $name) { /* on a new customer name ... */
if ($previous_name != "") {
/* if there is a previous customer, write the footer */
echo $footer; /* static HTML again like the header */
}
/* write the header for the new customer */
echo $header;
/* pick up the new customer name */
$previous_name = $name;
}
echo '
<tr>
<td width="149">
<center>'.$model.'</center>
</td>
<td width="149">
<center>'.date('d/m/Y', strtotime('+'.$year.' years',
strtotime($date))).'</center>
</td>
</tr>'; /* echos the model in first column and date+years in second column */
}
} /* end while ($data... */
/* wrap up the report by writing the final footer if need be */
if ( $previous_name != "" ) {
echo $footer; /* static HTML again like the header */
}
看看进展如何?您从SQL中请求一个详细的结果集,然后使用PHP中的一些编程技术按客户划分结果集。
这比获得一个GROUPed结果集然后尝试取消分组更容易、更可靠。
在foreach循环中,只需执行if语句来检查$row数据是否在您的日期范围内,如果是,则执行回显,否则不执行任何操作。
例如:
foreach ($models as $index => $model) {
if ($years[$index] >= DATE('2014-05-01') && $years[$index] <= DATE('2014-05-31')){
echo '
<tr>
<td width="149">
<center>'.$model.'</center>
</td>
<td width="149">
<center>'.date('d/m/Y', strtotime('+'.$years[$index].' years', strtotime($dates[$index]))).'</center>
</td>
</tr>';
}
}