如何将 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 中的字符串)是否是最好的方法。但是,如果您决定这样做,这应该可行。
好的,基本上我有一个 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 中的字符串)是否是最好的方法。但是,如果您决定这样做,这应该可行。