【问题标题】:Selecting from multiple tables, huge result从多个表中选择,巨大的结果
【发布时间】:2014-12-31 16:34:06
【问题描述】:

我正在尝试从 2 个表中选择项目,它应该返回 2 个结果,但我得到的结果超过 1000 个:

$sqlH = 'SELECT * FROM sheikh_tbl, wall';
$sqlH .= ' WHERE shk_fname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR shk_mname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR shk_lname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR (srub = "Sawtiyat" AND wtitle LIKE "%'.$keyword.'%")';

感谢您向我解释查询问题

编辑:使用 UNION ALL 代替 UNION

The default behavior for UNION is that duplicate rows are removed from the result. The optional DISTINCT keyword has no effect other than the default because it also specifies duplicate-row removal. With the optional ALL keyword, duplicate-row removal does not occur and the result includes all matching rows from all the SELECT statements.

【问题讨论】:

  • 然后呢?您对我们有什么期望?
  • 您将从使用 OR 语句开始。将为这些列中的任何一个返回匹配的结果。您可能想使用 and 而不是 OR?
  • 您返回的 1000 个结果 - 它们是否有效?您希望根据您的数据返回 2 个结果,还是希望将结果限制为仅返回 2 个结果?
  • 更好地使用内连接来匹配仅记录,这会导致每一行从一个表交叉连接到另一个。
  • 你可能是想加入表格?墙的目的是什么?它从未在查询中引用

标签: php sql


【解决方案1】:

Kritner 提供了答案,我只是想澄清一下以供您理解:

不推荐使用逗号分隔的表列表连接语法,当没有使用连接条件来过滤连接时,您会得到一个交叉连接/笛卡尔积:

表1:

ID
1
2
3

表2:

ID
4
5
6

所以这个查询:

SELECT *  FROM Table1,Table2

返回:

1,4
1,5
1,6
2,4
2,5
2,6
3,4
3,5
3,6

由于您的WHERE 条件是OR 语句的列表,因此您获得了所有记录,因为至少有一个条件与每个表中的一条记录匹配。您要么需要使用正确的连接,要么按照 Kritner 的建议,UNION 使用两个不相关的查询来获得一个结果集。

【讨论】:

  • (我觉得你的解释是我想要表达的,但你做得更好):)
【解决方案2】:

您缺少连接条件。否则,第一个表中的每一行都会与第二个表中的每一行相耦合。

假设两个表都有一个应该匹配的 id 列:

$sqlH = 'SELECT * FROM sheikh_tbl, wall';
$sqlH .= ' WHERE sheikh_tbl.id = wall.id';
$sqlH .= ' AND (shk_fname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR shk_mname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR shk_lname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR (srub = "Sawtiyat" AND wtitle LIKE "%'.$keyword.'%"))';

或者更好的是,您应该使用更现代的显式 join 语法:

$sqlH = 'SELECT * FROM sheikh_tbl';
$sqlH .= ' JOIN wall ON sheikh_tbl.id = wall.id';
$sqlH .= ' WHERE shk_fname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR shk_mname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR shk_lname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR (srub = "Sawtiyat" AND wtitle LIKE "%'.$keyword.'%")';

【讨论】:

  • 没有连接,我想从两个表中选择项目,它们之间没有任何关系
【解决方案3】:

你的问题很令人困惑......但基于 cmets 可能会这样做:

$sqlH = 'SELECT * FROM sheikh_tbl';
$sqlH .= ' WHERE shk_fname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR shk_mname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR shk_lname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR (srub = "Sawtiyat" AND wtitle LIKE "%'.$keyword.'%")';
$sqlH .= 'UNION SELECT * FROM wall';
$sqlH .= ' WHERE shk_fname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR shk_mname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR shk_lname LIKE "%'.$keyword.'%"';
$sqlH .= ' OR (srub = "Sawtiyat" AND wtitle LIKE "%'.$keyword.'%")';

这是假设您的架构在两个表之间是相同的,您的“,”意味着您声明不应该发生的连接。上面的查询是一样的,只是用一个联合分隔出来。可能会有所帮助,但发布您的架构以及为什么您期望 2 个结果会更有用。

【讨论】:

    【解决方案4】:

    我按照上面的建议使用了 UNION:

    $sqlH = 'SELECT shk_fname FROM sheikh_tbl';
    $sqlH .= ' WHERE shk_fname LIKE "%'.$keyword.'%"';
    $sqlH .= ' OR shk_mname LIKE "%'.$keyword.'%"';
    $sqlH .= ' OR shk_lname LIKE "%'.$keyword.'%"';
    $sqlH .= ' UNION SELECT srub FROM wall';
    $sqlH .= ' WHERE rub = "Sawtiyat" AND wtitle LIKE "%'.$keyword.'%"';
    

    所以它们是 2 个查询,结果是 2(这是错误的,我添加了一个新插入),如果我将它们分开,我得到的结果是 3(这是正确的)

    【讨论】:

      猜你喜欢
      • 2020-11-22
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多