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

rjee0c15  于 2021-06-21  发布在  Mysql
关注(0)|答案(5)|浏览(291)

不知道这是否可以做到,但我想问两个完全不同的要求调用不同的表在一个语句。最终结果将是找到的记录数量,该数量将为0或大于。
我了解如何在php中使用多个语句,但我的理解是,这将按顺序单独执行每个语句,这不是我需要做的。我需要知道这两条语句是否产生任何记录。
查询#1

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


查询#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
}
wgxvkvu9

wgxvkvu91#

@uuerdo有一个有效的答案(尽管有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 * . 与 SELECT * ,总执行时间为0.01237。我希望有人觉得学这个有用 SELECT * 不应该在生产环境中使用。

fv2wmkja

fv2wmkja2#

因为您只需要知道是否存在数据,而不需要知道数据是什么,这就足够了:

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\u行。

fae0ux8s

fae0ux8s3#

假设两个表包含相同的列,您可以使用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";

或者如果需要包含所有复制的行,则合并所有行
否则,应该明确地命名所需的列

$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 is sql。。您应该检查数据库驱动程序的参数绑定,以避免sql注入

8yparm6h

8yparm6h4#

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

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;

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

pgpifvop

pgpifvop5#

为了避免混淆,提出了几种可行的替代方案。
为了简洁起见,我将使用一个非常简单的sql查询,如下所示:

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

我还要解决一个似乎是一个巨大的sql注入漏洞。。。我们没有看到任何证据表明变量(例如$company\u id)可以安全地包含在sql文本中。
如果我们不打算使用带有bind占位符的prepared语句,那么我们需要正确地转义要包含在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" ;

相关问题