【问题标题】:Join csv files and sort to look like result from SQL query加入 csv 文件并排序以看起来像 SQL 查询的结果
【发布时间】:2017-09-23 21:32:01
【问题描述】:

我有 mysql 数据库,我在该数据库上运行带有连接和 where 子句的 sql 查询,假设查询看起来像

SELECT a.value1,
       a.value2,
       b.value3,
       c.value4
FROM table1 a
LEFT JOIN table2 b ON a.some_value=b.some_value
LEFT JOIN table3 c ON a.some_value=c.some_value
WHERE a.some_value = 'some_text';

并且我运行查询 1000 次以获得此查询在具有 450 万条记录的数据库上所需的平均时间。

但是,如果可能的话,我需要帮助 因为我不知道这是否可能,如果可能,该怎么做,以及从哪里开始下一步。

这些步骤是:我想导出 CSV 文件 table1、table2 和 table3(没关系,我知道要在 csv 文件中导出表),之后,在 PHP 中,我想加载每个 csv 文件,并获得几乎与此 SQL 查询相同的结果。 我也想运行这个查询 1.000 次并获得平均时间。我想做这些来比较对表运行查询和从 csv 文件排序。

【问题讨论】:

  • 你到底想让我们做什么,除了建议你几乎肯定会等待很长时间,甚至从 csv 文件执行一次,更不用说 1000 次了,编码这样做需要几小时/几天而不是几分钟......可以做到,但你为什么要让自己经历痛苦呢?
  • @MarkBaker 因为我想进行比较,因为我想学习,但我不知道如何可能以及从哪里开始,因为我还没有做过这种,以及起点,做什么会很有帮助,因为在那之后我也想从 python 测试这个,在 mysql 上执行大约需要 50 秒,我想知道它是如何从 php 完成的以及需要什么时间
  • @MarkBaker 有很多方法,我们可以每天编码,做或多或少相同的工作,相同的任务,或者你可以做编程,并尝试学习新的方法,这个,我真的不知道,我想我知道需要做什么,但我真的不知道怎么做,老实说,我不知道
  • 给我 5 分钟的时间为你写一个骨架......你会从中学到一些东西,如果你想要任何形式的表现就不要这样做
  • @MarkBaker 好的,非常感谢,欢迎任何形式的帮助

标签: php mysql arrays csv


【解决方案1】:

如果你真的要让自己经历这种痛苦,至少这是一个相当简单的查询。

类似

$a = fopen('a.csv', 'r');
$b = fopen('b.csv', 'r');
$c = fopen('c.csv', 'r');
$output = fopen('php://output', 'w');

while (($dataA = fgetcsv($a, 1024, ",")) !== false) {
    if ($dataA[0] == 'some_text') {
        $bCount = 0;
        rewind($b);
        while (($dataB = fgetcsv($b, 1024, ",")) !== false) {
            if ($dataB[0] == $dataA[3]) {
                $bCount = 0;
                $cCount = 0;
                rewind($c);
                while (($dataC = fgetcsv($c, 1024, ",")) !== false) {
                    if ($dataC[0] == $dataA[4]) {
                        fputcsv($output, [$dataA[1], $dataA[2], $dataB[1], $dataC[1]]);
                        ++$cCount;
                    }
                }
                if ($cCount == 0) {
                    fputcsv($output, [$dataA[1], $dataA[2], $dataB[1], null]);
                }
                ++$bCount;
            }
        }
        if ($bCount == 0) {
            $cCount = 0;
            rewind($c);
            while (($dataC = fgetcsv($c, 1024, ",")) !== false) {
                if ($dataC[0] == $dataA[4]) {
                    fputcsv($output, [$dataA[1], $dataA[2], null, $dataC[1]]);
                    ++$cCount;
                }
            }
            if ($cCount == 0) {
                fputcsv($output, [$dataA[1], $dataA[2], null, null]);
            }
        }
    }
}

会非常接近你想要的。

修改您的行 ID 以适合您的查询。如果你想在每一行中“命名”你的单元格以使代码更“可读”,那么这是一个开销,而且这将需要足够长的时间才能运行


编辑

从逻辑上讲,它遍历文件 a,依次测试每一行以查看它是否符合您的 where 条件,忽略任何不匹配的行并继续下一个。如果它确实找到了匹配项,那么它会对文件 b 进行查找,循环直到找到任何匹配项(那里的 if 测试)。如果它确实找到了与 b 的匹配项,则它会针对 c 循环。如果找到与 c 的匹配项(再次进行 if 测试),则会显示结果(将您选择的值写入所有 3 个文件的逗号分隔列表)。如果在 c 中未找到匹配项,则它将 a 和 b 中的值显示为 null,而不是 c 中的任何值。如果在 b 中没有找到匹配的值,那么它会针对 c 循环寻找匹配,并显示来自 a 和 c 的任何匹配项,对于来自 b 的选择值显示为空。如果在 b 或 c 中都没有找到匹配的值,则它显示 b 和 c 单元格的 a 值为空值。 b 和 c 循环的倒带确保循环总是从文件的开头开始检查。


除了遍历整个文件之外,没有其他简单的方法可以搜索 csv。如果您有无限的内存,您可以循环遍历每个文件一次针对索引缓存结果,以使后续循环更容易,但 PHP 不是内存密集型任务的正确语言。

当然,如果有无限的内存并且可以将每个文件的全部加载到 3 个数组中,那么您可以使用 LINQ 之类的查询工具来处理查询

【讨论】:

  • 首先,非常感谢您的帮助,我非常感谢您的时间和精力,这对我来说真的很重要,老实说,我什至现在都不知道这是做什么的,我已经添加了我的 csv部分“一些文本”的文件我输入了我想要的内容,它返回一行值,但我不知道为什么它会返回该值,所以我会看看我能做什么,这不是我做的想要,但可能是一个很好的起点,我会接受你的回答。我必须说,我想了解一下你的逻辑和思维,这样我就可以像你一样写算法,非常感谢马克,你太棒了!
猜你喜欢
  • 2020-01-02
  • 1970-01-01
  • 2014-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-21
相关资源
最近更新 更多