如何使用 fputcsv 拆分 sql 查询的导出
How to split the export of a sql query with fputcsv
我的 sql 查询有一个简单的 fputcsv 命令。但有时我的导出有更多行和不同的主键。我的愿望是使用不同的主键将每个结果拆分为新的 csv 导出。
示例:
| *row 1 | row 2 | row 3 |
|.......27 |......45 |......aa |
|.......27 |......35 |......ab |
|.......28 |......85 |......bb |
|.......28 |......65 |......bc |
实际情况:第1行有主键(order_id)。我 运行 每天都有一个 cronjob 处理所有订单。因此该文件有多个订单(如上例 = 订单 27、订单 28 等)。我的供应商需要为每个订单提供一个 csv 文件。所以我需要一个代码,它将查询拆分为 "if order_id is different so create a new file...and so on..."。这可能吗?
<?php
$servername = "Jarvis";
$username = "TonyStark";
$password = "iLoveIronMan";
$dbname = "TheAnvengers";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT o.order_id, o.customer_id, op.quantity, op.model FROM oc_order o INNER JOIN oc_order_product op ON o.order_id = op.order_id INNER JOIN oc_product p ON op.product_id = p.product_id WHERE o.order_status_id = 2 AND p.location = 1 ORDER BY o.order_id, op.model";
$file = fopen('../files/in/filename.csv', 'w');
if ($rows = mysqli_query($conn, $sql)) {
while ($row = mysqli_fetch_assoc($rows)) {
fputcsv($file, $row, ';');
}
mysqli_free_result($rows);
}
mysqli_close($conn);
fclose($file);
?>
为什么不直接使用 order_id 作为文件名,将 fopen
和 fclose
移动到循环中,并更改 fopen
以在追加模式下工作。
<?php
// connect to the database
$servername = "Jarvis";
$username = "TonyStark";
$password = "iLoveIronMan";
$dbname = "TheAnvengers";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Get the data
$sql = "SELECT o.order_id, o.customer_id, op.quantity, op.model FROM oc_order o INNER JOIN oc_order_product op ON o.order_id = op.order_id INNER JOIN oc_product p ON op.product_id = p.product_id WHERE o.order_status_id = 2 AND p.location = 1 ORDER BY o.order_id, op.model";
$orders = array(); // For storing the data by order_id
// Loop through the result set and populate $orders
if ($rows = mysqli_query($conn, $sql)) {
while ($row = mysqli_fetch_assoc($rows)) {
// This is where the split on order_id occurs
$orders[$row['order_id']][] = $row;
/*
$orders will now look like this after the first iteration
$orders = array(
27 => array(
0 => array(
'order_id' => 27,
'customer_id' => 45,
'quantity' => aa,
'model' => someModel
)
)
);
==============================
$orders will look like this after the last iteration
$orders = array(
27 => array(
0 => array(
'order_id' => 27,
'customer_id' => 45,
'quantity' => aa,
'model' => someModel
),
1 => array(
'order_id' => 27,
'customer_id' => 35,
'quantity' => ab,
'model' => someModel
),
28 => array(
0 => array(
'order_id' => 28,
'customer_id' => 85,
'quantity' => bb,
'model' => someModel
),
1 => array(
'order_id' => 28,
'customer_id' => 65,
'quantity' => bc,
'model' => someModel
)
);
*/
}
mysqli_free_result($rows);
}
mysqli_close($conn);
// Loop through $orders (by order_id)
foreach($orders as $id => $order)
{
// Open the file for writing, blanking existing file or creating if non-existent - name it after the order_id
$f = fopen('../files/in/' . $id . '.csv', 'w');
// Loop through each $row for that particular order_id and put it into the csv
foreach($order as $entry)
{
fputcsv($f, $entry, ';');
}
fclose($f);
}
?>
我的 sql 查询有一个简单的 fputcsv 命令。但有时我的导出有更多行和不同的主键。我的愿望是使用不同的主键将每个结果拆分为新的 csv 导出。
示例:
| *row 1 | row 2 | row 3 |
|.......27 |......45 |......aa |
|.......27 |......35 |......ab |
|.......28 |......85 |......bb |
|.......28 |......65 |......bc |
实际情况:第1行有主键(order_id)。我 运行 每天都有一个 cronjob 处理所有订单。因此该文件有多个订单(如上例 = 订单 27、订单 28 等)。我的供应商需要为每个订单提供一个 csv 文件。所以我需要一个代码,它将查询拆分为 "if order_id is different so create a new file...and so on..."。这可能吗?
<?php
$servername = "Jarvis";
$username = "TonyStark";
$password = "iLoveIronMan";
$dbname = "TheAnvengers";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT o.order_id, o.customer_id, op.quantity, op.model FROM oc_order o INNER JOIN oc_order_product op ON o.order_id = op.order_id INNER JOIN oc_product p ON op.product_id = p.product_id WHERE o.order_status_id = 2 AND p.location = 1 ORDER BY o.order_id, op.model";
$file = fopen('../files/in/filename.csv', 'w');
if ($rows = mysqli_query($conn, $sql)) {
while ($row = mysqli_fetch_assoc($rows)) {
fputcsv($file, $row, ';');
}
mysqli_free_result($rows);
}
mysqli_close($conn);
fclose($file);
?>
为什么不直接使用 order_id 作为文件名,将 fopen
和 fclose
移动到循环中,并更改 fopen
以在追加模式下工作。
<?php
// connect to the database
$servername = "Jarvis";
$username = "TonyStark";
$password = "iLoveIronMan";
$dbname = "TheAnvengers";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Get the data
$sql = "SELECT o.order_id, o.customer_id, op.quantity, op.model FROM oc_order o INNER JOIN oc_order_product op ON o.order_id = op.order_id INNER JOIN oc_product p ON op.product_id = p.product_id WHERE o.order_status_id = 2 AND p.location = 1 ORDER BY o.order_id, op.model";
$orders = array(); // For storing the data by order_id
// Loop through the result set and populate $orders
if ($rows = mysqli_query($conn, $sql)) {
while ($row = mysqli_fetch_assoc($rows)) {
// This is where the split on order_id occurs
$orders[$row['order_id']][] = $row;
/*
$orders will now look like this after the first iteration
$orders = array(
27 => array(
0 => array(
'order_id' => 27,
'customer_id' => 45,
'quantity' => aa,
'model' => someModel
)
)
);
==============================
$orders will look like this after the last iteration
$orders = array(
27 => array(
0 => array(
'order_id' => 27,
'customer_id' => 45,
'quantity' => aa,
'model' => someModel
),
1 => array(
'order_id' => 27,
'customer_id' => 35,
'quantity' => ab,
'model' => someModel
),
28 => array(
0 => array(
'order_id' => 28,
'customer_id' => 85,
'quantity' => bb,
'model' => someModel
),
1 => array(
'order_id' => 28,
'customer_id' => 65,
'quantity' => bc,
'model' => someModel
)
);
*/
}
mysqli_free_result($rows);
}
mysqli_close($conn);
// Loop through $orders (by order_id)
foreach($orders as $id => $order)
{
// Open the file for writing, blanking existing file or creating if non-existent - name it after the order_id
$f = fopen('../files/in/' . $id . '.csv', 'w');
// Loop through each $row for that particular order_id and put it into the csv
foreach($order as $entry)
{
fputcsv($f, $entry, ';');
}
fclose($f);
}
?>