如何将 SQL 查询的结果用于另一个查询的 WHERE 子句?

How can I use an SQL query's result for the WHERE clause of another query?

好的,基本上我有一个 table,其中包含如下语句:

incident.client_category = 1
incident.client_category = 8
incident.severity = 1
etc.

我想使用此 table 中的内容来生成其他 table 满足此中表达的条件。所以我需要把它做成

SELECT * FROM incident WHERE incident.client_category = 1

但是 where 的最后一部分必须来自第一部分 table。现在我想做的是

SELECT * FROM incident WHERE (SELECT condition FROM condition WHERE id = 1)

id = 1 代表条件的id。现在我只想使用一个条件进行测试。有没有办法做到这一点?因为如果没有,我可能不得不通过 PHP 将第一个查询的结果解析到我的事件查询中。

Table 模式:

这是一种通过使用所谓的 dynamic sql 来实现您的目标的方法,请注意,这仅适用于 select 从条件 table returns 只有一条记录.

declare @SQLSTRING varchar(4000)
,  @condition VARCHAR(500) -- change the size to whatever condition column size is

SELECT @condition = condition
FROM
    condition
WHERE
    id = 1
 SET @SQLSTRING= 'SELECT  * FROM incident WHERE  ' + @condition
                
exec sp_executesql(@SQLSTRING)

工程建议-标准化DB

在 MySQL table 的字段中存储 WHERE 子句,如 id = 10,不是一个好主意。我建议看看 MySQL Normalization。您不应该将 id = 10 存储为 varchar,而应该存储类似 OtherTableid 的内容。这允许您使用索引,优化您的数据库,并获得大量其他功能,这些功能是您通过将字段用作 WHERE 子句而被剥夺的。

但有时我们需要尽快找到解决方案,但我们无法重新设计一切!那么让我们来看看制作一个...

解决方案

这里有一个解决方案,即使在 MySQL 的非常旧的 v.5.0 版本上也可以使用。使用 SET 设置变量,使用 PREPARE 准备语句,并使用 EXECUTE 执行它。让我们将查询设置为一个变量...

SET @query = CONCAT(
     "SELECT * FROM incident WHERE ",
     (SELECT condition FROM condition WHERE id = 1)
);

我知道这应该有效,因为以下内容绝对适用于我的系统(不需要构建任何新的 table 或架构更改)...

SET @query = CONCAT("SELECT id FROM myTable WHERE id = ", (SELECT MAX(id) FROM myTable));

如果我 SELECT @query;,我得到:SELECT id FROM myTable WHERE id = 1737901。现在,我们需要做的就是 运行 这个查询!

PREPARE stmt1 FROM @query; 
EXECUTE stmt1; 
DEALLOCATE PREPARE stmt1; 

这里我们使用一个prepare to build the query, execute to execute it, and deallocate来为下一个prepared statement做准备。在我自己上面的示例中,任何人都可以在不更改数据库架构的情况下对其进行测试,我得到了良好的积极结果:EXECUTE stmt1; 给了我...

| id | 1737901 | .

由于您还用 PHP 标记了问题,我建议使用它。只需 select 来自条件 table 的字符串,并使用结果构建包含它的 SQL 查询(作为 PHP 中的字符串)。然后运行第二次查询。伪代码(跳过你用来调用数据库的 library/framework):

$query = "select condition from condition where id = :id";
$condition = callDbAndReturnString($query, $id);
$query = "select * from incident where " . $condition;
$result = callDb($query);

但是,要非常小心。您在哪里以及如何填充条件 table 中的可能值?甚至您的用户如何选择使用哪一个?如果您允许用户生成值并将它们存储在那里,您 运行 将面临二次 SQL 注入攻击的风险。由于您将条件 table 中的值用作字符串,因此您不能像通常那样(希望如此!)使用它来参数化查询。根据您 运行 的查询以及作为条件的可能值,即使您只是让他们从预先构建的列表中选择,也可能存在风险。我会认真地问自己这(将 SQL 查询的部分内容保存为另一个 table 中的字符串)是否是最好的方法。但是,如果您决定这样做,这应该可行。