【问题标题】:How do I filter a php array with a MySQL table?如何使用 MySQL 表过滤 php 数组?
【发布时间】:2010-09-18 05:43:31
【问题描述】:

假设我在一个名为 $foo 的 php 数组中有一个字符串数组,其中包含数百个条目,并且我有一个 MySQL 表“people”,其中有一个名为“name”的字段,其中包含数千个条目。在不为 $foo 中的每个字符串提交查询的情况下,找出 $foo 中的哪些字符串不是 'people' 条目中的 'name' 的有效方法是什么?

所以我想找出 $foo 中的哪些字符串还没有被输入到 'people' 中。

请注意,很明显,所有数据都必须在一个盒子上。这样做的目标是同时最大限度地减少查询数量和 php 处理量。

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    除了将所有字符串提交到数据库之外,我不确定是否有更有效的方法来做到这一点。

    基本上有两种选择:获取 MySQL 中所有字符串的列表并将它们拉入 PHP 并进行比较,或者将所有字符串的列表发送到 MySQL 服务器并让它进行比较。 MySQL 将比 PHP 更快地进行比较,除非数据库中的列表比 PHP 中的列表小很多。

    您可以创建一个临时表,但无论哪种方式,您都可以将所有数据推送到数据库。

    【讨论】:

    • 你能举个例子说明长选择语句的样子吗?
    • 进一步思考,长选择可能行不通,您需要接受临时表的想法作为正确答案。
    【解决方案2】:

    下面的呢:

    1. 获取数据库中已经存在的名称列表,使用类似: SELECT name FROM people WHERE name IN (imploded list of names)
    2. 插入array_diff()返回的每一项

    如果你想完全在 SQL 中完成:

    1. 使用 PHP 数组中的每个名称创建一个临时表。
    2. 执行查询以填充仅包含新名称的第二个临时表。
    3. 将第二个临时表中的INSERT ... SELECT 放入人员表中。

    两者都不会非常快,尽管第二个选项可能会稍微快一些。

    【讨论】:

      【解决方案3】:
      CREATE TEMPORARY TABLE PhpArray (name varchar(50));
      
      -- you can probably do this more efficiently
      INSERT INTO PhpArray VALUES ($foo[0]), ($foo[1]), ...;
      
      SELECT People.*
      FROM People
       LEFT OUTER JOIN PhpArray USING (name)
      WHERE PhpArray.name IS NULL;
      

      【讨论】:

        【解决方案4】:
        $query = 'SELECT name FROM table WHERE name != '.implode(' OR name != '. $foo);
        

        是的,这看起来根本无法很好地扩展。

        【讨论】:

        • 应该是“AND”,而不是“OR”。
        【解决方案5】:

        不使用临时表我能想到的最好的方法是:

         $list = join(",", $foo);
        
        // fetch all rows of the result of 
        // "SELECT name FROM people WHERE name IN($list)" 
        // into an array $result
        
        $missing_names = array_diff($foo, $result);
        

        请注意,如果 $foo 包含用户输入,则必须先对其进行转义。

        【讨论】:

        • 确认!没有占位符!未引用!没有逃脱!
        • 嗯,注释行显然是伪代码。我提到了缺乏逃生,不是吗?不引用是一个遗漏,我的错。
        【解决方案6】:

        对于几百个条目,只需使用 array_diff() 或 array_diff_assoc()

        【讨论】:

          【解决方案7】:

          我会将您的 $foo 数据放在另一个表中,并与您的名称表进行 LEFT OUTER JOIN。否则,在某些时候没有很多不涉及迭代的好方法。

          【讨论】:

          • 你将如何使用 LEFT JOIN 返回名称表中的 $foo 日期not
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-05-14
          • 2017-07-09
          • 2011-02-15
          • 2019-02-26
          • 2013-07-17
          • 1970-01-01
          • 2011-08-28
          相关资源
          最近更新 更多