Php 从一个 mysql 查询创建多个 csv 文件
Php to create multiple csv(s) files from one mysql query
更新 #1
我有一个 php 文件,其中包含创建多个 csv 文件的多个查询。
我想合并查询。
我的 mysql table
有 5 列:ID、货币、汇率、日期、临时时间
创建 table table
并插入一些记录
CREATE TABLE IF NOT EXISTS `table` ( `id` INT NOT NULL AUTO_INCREMENT , `currency` VARCHAR(254) NOT NULL , `rate` FLOAT NOT NULL , `date` VARCHAR(254) NOT NULL , `temptime` DATE NOT NULL , PRIMARY KEY (`id`), UNIQUE `UNIQUE` (`currency`, `temptime`)) ENGINE = MyISAM;
INSERT INTO `table`
(currency, rate, date, temptime)
VALUES
('USD', '1.232', '1521212400', '2018-03-16'),
('USD', '1.258', '1521126000', '2018-03-15'),
('JPY', '133.82', '1521212400', '2018-03-16'),
('JPY', '131.88', '1521126000', '2018-03-15'),
('EUR', '1.99', '1521212400', '2018-03-16'),
('EUR', '1.85', '1521126000', '2018-03-15'),
('BRL', '1.6654', '1521212400', '2018-03-16'),
('BRL', '1.5498', '1521126000', '2018-03-15'),
('ZAR', '1.99654', '1521212400', '2018-03-16'),
('ZAR', '2.0198', '1521126000', '2018-03-15'),
('RUB', '19.9654', '1521212400', '2018-03-16'),
('RUB', '20.0198', '1521126000', '2018-03-15');
这些是我要为 "currency" 美元和欧元列合并的 2 个查询:
$result = mysql_query("SELECT temptime, rate FROM `table` WHERE currency='USD' ORDER BY date asc");
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++)
{
$headers[] = mysql_field_name($result , $i);
}
$fp = fopen('csv/USD.csv', 'w');
if ($fp && $result)
{
fputcsv($fp, $headers);
while ($row = mysql_fetch_row($result))
{
fputcsv($fp, array_values($row));
}
}
$result = mysql_query("SELECT temptime, rate FROM `table` WHERE currency='EUR' ORDER BY date asc");
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++)
{
$headers[] = mysql_field_name($result , $i);
}
$fp = fopen('csv/EUR.csv', 'w');
if ($fp && $result)
{
fputcsv($fp, $headers);
while ($row = mysql_fetch_row($result))
{
fputcsv($fp, array_values($row));
}
}
谢谢
您可以使用每行中的货币字段来决定要写入哪个文件,我使用了一个文件句柄数组,因此您无需围绕哪个文件设置任何条件,只需使用货币作为索引即可文件句柄...
// Create an array of files, each associated with currency
$fp = array( 'EUR' => fopen('csv/EUR.csv', 'w'),
'USD' => fopen('csv/USD.csv', 'w'));
$result = mysql_query("SELECT currency, temptime, rate FROM `table` ORDER BY date asc");
if (!$result) die("Couldn't fetch records");
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++)
{
$headers[] = mysql_field_name($result , $i);
}
// Write out headers to each file.
foreach ( $fp as $output ) {
fputcsv($output, $headers);
}
while ($row = mysql_fetch_row($result)) {
// Use first field to decide which file to write to.
$currency = array_shift($row);
fputcsv($fp[$currency], $row);
}
// Close all of the files.
foreach ( $fp as $output ) {
fclose($output);
}
因为我没有你的数据库,所以我无法测试这个,但是如果你有任何问题,请告诉我。
也考虑不使用循环并直接从 MySQL 及其 SELECT ... INTO OUTFILE
(LOAD DATA INFILE
的补充)导出到 CSV。
具体来说,在下面 PHP 中分别执行两个操作查询(一定要转义引号)。虽然没有合并,但这个过程应该是一个比多个循环更快的 read/write IO 过程。另外,您可以在不更改 csv 导出代码的情况下交换应用层(即使用 Python、Java)!
SELECT temptime, rate
INTO OUTFILE '/path/to/csv/USD.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM `table`
WHERE currency='USD'
ORDER BY `date` asc;
SELECT temptime, rate
INTO OUTFILE '/path/to/csv/EUR.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM `table`
WHERE currency='EUR'
ORDER BY `date` asc;
并且对于一个调用,都放在 MySQL 存储过程中:
DELIMITER $$
DROP PROCEDURE IF EXISTS export_csv$$
CREATE PROCEDURE export_csv
BEGIN
-- SELECT ... INTO OUTFILE COMMANDS
END$$
DELIMITER ;
然后在PHP运行中加上one-liner(使用mysqli
API):
$result = mysqli_query($conn, "CALL export_csv")
请注意:headers 未通过上述命令传递。使用需要类型转换的联合解决调整查询。而且 CSV 不存储类型或 unicodes 元数据,所以这里有问题。
SELECT 'temptime' as col1, 'rate' as col2
UNION ALL
SELECT CAST(temptime, CHAR(10) as col1,
CAST(ROUND(rate,4) AS CHAR(3)) as col2
INTO OUTFILE '/path/to/csv/USD.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM `table`
WHERE currency='USD' ;
更新 #1 我有一个 php 文件,其中包含创建多个 csv 文件的多个查询。 我想合并查询。
我的 mysql table
有 5 列:ID、货币、汇率、日期、临时时间
创建 table table
并插入一些记录
CREATE TABLE IF NOT EXISTS `table` ( `id` INT NOT NULL AUTO_INCREMENT , `currency` VARCHAR(254) NOT NULL , `rate` FLOAT NOT NULL , `date` VARCHAR(254) NOT NULL , `temptime` DATE NOT NULL , PRIMARY KEY (`id`), UNIQUE `UNIQUE` (`currency`, `temptime`)) ENGINE = MyISAM;
INSERT INTO `table`
(currency, rate, date, temptime)
VALUES
('USD', '1.232', '1521212400', '2018-03-16'),
('USD', '1.258', '1521126000', '2018-03-15'),
('JPY', '133.82', '1521212400', '2018-03-16'),
('JPY', '131.88', '1521126000', '2018-03-15'),
('EUR', '1.99', '1521212400', '2018-03-16'),
('EUR', '1.85', '1521126000', '2018-03-15'),
('BRL', '1.6654', '1521212400', '2018-03-16'),
('BRL', '1.5498', '1521126000', '2018-03-15'),
('ZAR', '1.99654', '1521212400', '2018-03-16'),
('ZAR', '2.0198', '1521126000', '2018-03-15'),
('RUB', '19.9654', '1521212400', '2018-03-16'),
('RUB', '20.0198', '1521126000', '2018-03-15');
这些是我要为 "currency" 美元和欧元列合并的 2 个查询:
$result = mysql_query("SELECT temptime, rate FROM `table` WHERE currency='USD' ORDER BY date asc");
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++)
{
$headers[] = mysql_field_name($result , $i);
}
$fp = fopen('csv/USD.csv', 'w');
if ($fp && $result)
{
fputcsv($fp, $headers);
while ($row = mysql_fetch_row($result))
{
fputcsv($fp, array_values($row));
}
}
$result = mysql_query("SELECT temptime, rate FROM `table` WHERE currency='EUR' ORDER BY date asc");
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++)
{
$headers[] = mysql_field_name($result , $i);
}
$fp = fopen('csv/EUR.csv', 'w');
if ($fp && $result)
{
fputcsv($fp, $headers);
while ($row = mysql_fetch_row($result))
{
fputcsv($fp, array_values($row));
}
}
谢谢
您可以使用每行中的货币字段来决定要写入哪个文件,我使用了一个文件句柄数组,因此您无需围绕哪个文件设置任何条件,只需使用货币作为索引即可文件句柄...
// Create an array of files, each associated with currency
$fp = array( 'EUR' => fopen('csv/EUR.csv', 'w'),
'USD' => fopen('csv/USD.csv', 'w'));
$result = mysql_query("SELECT currency, temptime, rate FROM `table` ORDER BY date asc");
if (!$result) die("Couldn't fetch records");
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++)
{
$headers[] = mysql_field_name($result , $i);
}
// Write out headers to each file.
foreach ( $fp as $output ) {
fputcsv($output, $headers);
}
while ($row = mysql_fetch_row($result)) {
// Use first field to decide which file to write to.
$currency = array_shift($row);
fputcsv($fp[$currency], $row);
}
// Close all of the files.
foreach ( $fp as $output ) {
fclose($output);
}
因为我没有你的数据库,所以我无法测试这个,但是如果你有任何问题,请告诉我。
也考虑不使用循环并直接从 MySQL 及其 SELECT ... INTO OUTFILE
(LOAD DATA INFILE
的补充)导出到 CSV。
具体来说,在下面 PHP 中分别执行两个操作查询(一定要转义引号)。虽然没有合并,但这个过程应该是一个比多个循环更快的 read/write IO 过程。另外,您可以在不更改 csv 导出代码的情况下交换应用层(即使用 Python、Java)!
SELECT temptime, rate
INTO OUTFILE '/path/to/csv/USD.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM `table`
WHERE currency='USD'
ORDER BY `date` asc;
SELECT temptime, rate
INTO OUTFILE '/path/to/csv/EUR.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM `table`
WHERE currency='EUR'
ORDER BY `date` asc;
并且对于一个调用,都放在 MySQL 存储过程中:
DELIMITER $$
DROP PROCEDURE IF EXISTS export_csv$$
CREATE PROCEDURE export_csv
BEGIN
-- SELECT ... INTO OUTFILE COMMANDS
END$$
DELIMITER ;
然后在PHP运行中加上one-liner(使用mysqli
API):
$result = mysqli_query($conn, "CALL export_csv")
请注意:headers 未通过上述命令传递。使用需要类型转换的联合解决调整查询。而且 CSV 不存储类型或 unicodes 元数据,所以这里有问题。
SELECT 'temptime' as col1, 'rate' as col2
UNION ALL
SELECT CAST(temptime, CHAR(10) as col1,
CAST(ROUND(rate,4) AS CHAR(3)) as col2
INTO OUTFILE '/path/to/csv/USD.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM `table`
WHERE currency='USD' ;