2个完全不同的查询在1个语句mysql中

时间:2018-05-01 19:50:24

标签: php mysql

不确定是否可以这样做,但我想问两个完全不同的quires在一个语句中调用不同的表。最终结果可能是找到的记录数量为0或大于。

我理解在php中使用Multiple Statements但是我的理解是,这将按顺序执行每一个,这不是我需要做的。我需要知道两个语句是否产生任何记录。

查询#1

$sql = "SELECT * FROM table1 WHERE company_id = '$company_id ' AND email = '$email'";

OR

查询#2

$sql = "SELECT * FROM table2 WHERE company_id = '$company_id ' AND column = 1";

我需要将它们与OR结合起来,因为如果其中任何一个产生记录,那么我需要继续。

最终

$sql = "(SELECT * FROM table1 WHERE company_id = '$company_id ' AND email = '$email') OR (SELECT * FROM table2 WHERE company_id = '$company_id ' AND column = 1)";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
    // do something
}

5 个答案:

答案 0 :(得分:2)

由于您只需要知道是否有数据,而不是数据是什么,这应该足够了:

SELECT CASE WHEN (EXISTS (SELECT * FROM table1 WHERE company_id = '$company_id ' AND email = '$email') 
    OR EXISTS (SELECT * FROM table2 WHERE company_id = '$company_id ' AND column = 1)
) THEN 1 ELSE 0 END AS hasData;

它恰好也是你所寻找的最直接的表达方式。

请注意,您不需要检查num_rows,而是需要检查返回的单个结果行的单个列上的字段值。

答案 1 :(得分:0)

假设两个表包含相同的列您可以使用UNION(用于不同的行)

$sql = "SELECT * FROM table1 WHERE company_id = '$company_id ' AND email = '$email'
      UNION 
      SELECT * FROM table2 WHERE company_id = '$company_id ' AND column = 1";

OR UNION ALL如果您需要包含所有已删除的行

否则你应该明确命名你需要的列

$sql = "SELECT col1, col2, col3 ... FROM table1 WHERE company_id = '$company_id ' AND email = '$email'
      UNION 
      SELECT col1, col2, col3 ... FROM table2 WHERE company_id = '$company_id ' AND column = 1";

最后小心使用php var是sql ..你应该检查你的db驱动程序param绑定以避免sql注入

答案 2 :(得分:0)

下面的查询将返回匹配的行数和与行匹配的查询。如果只有一个查询返回行,则输出将是一行,如果两个查询匹配,则返回两行。

SELECT 
    '1' as `querythatmatched`,
    COUNT(*) as `nummatched`
FROM TABLE1
WHERE `company_id` = '$company_id' AND `email` = '$email'
UNION
SELECT 
    '2' as `querythatmatched`,
    COUNT(*) as `nummatched`
FROM TABLE2
WHERE `company_id` = '$company_id' AND `column` = 1;

BTW,这并不关心两个表中存在哪些列(where子句除外),因此它可以用于任何表/列类型。

答案 3 :(得分:0)

不要混淆,提出了几种可行的替代方案。

为了简洁,我会使用一个非常简单的SQL查询,如下所示:

 SELECT 1 FROM table1 t1 WHERE t1.company_id ...
 UNION ALL
 SELECT 2 FROM table2 t2 WHERE t2.company_id ...

我还解决了似乎是目标 SQL注入漏洞的问题......我们没有看到任何证据证明变量,例如保证$ company_id可以安全地包含在SQL文本中。

如果我们不打算使用带有绑定占位符的预准备语句,那么我们需要正确地转义要包含在SQL中的值

内联生成SQL文本

 $sql = "SELECT 1 FROM table1 t1 WHERE t1.company_id = "
      . "'" . $conn->real_escape_string($company_id) . "'"
      . " AND t1.email = "
      . "'" . $conn->real_escape_string($email) . "'"
      . " UNION ALL"
      . " SELECT 2 FROM table2 t2 WHERE t2.company_id = "
      . "'" . $conn->real_escape_string($company_id) . "'"
      . " AND t2.column = 1" ;

- 或 -

作为SQL

构造之前的单独分配
 $es_company_id = $conn->real_escape_string($company_id);
 $es_email      = $conn->real_escape_string($email);
 $sql = "SELECT 1 FROM table1 t1 WHERE t1.company_id = '$es_company_id'"
      . " AND t1.email = '$es_email'"
      . " UNION ALL"
      . " SELECT 2 FROM table2 t2 WHERE t2.company_id = '$es_company_id'"
      . " AND t2.column = 1" ;

答案 4 :(得分:0)

@Uueerdo有一个有效的答案(尽管SQL注入的东西,但这不是OP所要求的)。如果我可以稍微改变以提高查询的速度,我会提供:

SELECT CASE WHEN (EXISTS (SELECT 1 FROM table1 WHERE company_id ='$company_id ' AND email = '$email') 
    OR EXISTS (SELECT 1 FROM table2 WHERE company_id = '$company_id ' AND column = 1)
) THEN 1 ELSE 0 END AS hasData;

我在SQLYog中对此进行了基准测试,发现当在子选择中使用SELECT 1而不是SELECT *时,总执行时间为0.00055。使用SELECT *,总执行时间为0.01237。我希望有人发现有必要了解SELECT *可能不应该在生产环境中使用。