[英]How can I use an SQL query's result for the WHERE clause of another query?
好的,基本上我有一个包含如下语句的表:
incident.client_category = 1
incident.client_category = 8
incident.severity = 1
etc.
我想使用该表中的内容生成满足该表中表达的条件的其他表。 所以我需要让它像
SELECT * FROM incident WHERE incident.client_category = 1
但是 where 的最后一部分必须来自第一个表。 现在我想做的是
SELECT * FROM incident WHERE (SELECT condition FROM condition WHERE id = 1)
id = 1 代表条件的id。 现在我只想使用一个条件进行测试。 有没有办法做到这一点? 因为如果没有,我可能不得不将第一个查询的结果通过 PHP 解析到我的事件查询中。
表架构:
工程建议-标准化数据库
在 MySQL 表的字段中存储 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)
);
我知道这应该有效,因为以下内容绝对适用于我的系统(不需要构建任何新表或架构更改)...
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
来构建查询, execute
来执行它,并deallocate
为下一个准备好的语句做好准备。 在我自己上面的示例中,任何人都可以在不更改数据库模式的情况下进行测试,我得到了良好的积极结果: EXECUTE stmt1;
给我...
| id | 1737901 |
.
这是通过使用所谓的dynamic sql
来实现您的目标的一种方法,请注意,这仅适用于条件表中的 select 仅返回一条记录。
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)
由于您还用 PHP 标记了问题,我建议使用它。 只需 select 条件表中的字符串,并使用结果构建一个包含它的 SQL 查询(作为 PHP 中的字符串)。 然后运行第二个查询。 伪代码(跳过你用来调用数据库的库/框架):
$query = "select condition from condition where id = :id";
$condition = callDbAndReturnString($query, $id);
$query = "select * from incident where " . $condition;
$result = callDb($query);
但是,要非常小心。 您在哪里以及如何填充条件表中的可能值? 甚至您的用户如何选择使用哪一个? 如果您允许用户生成值并将它们存储在那里,您将面临二次 SQL 注入攻击的风险。 由于您将条件表中的值用作字符串,因此您不能像通常那样(希望如此)对使用它的查询进行参数化,具体取决于您运行的查询和可能的值作为条件。 即使您只是让他们从预先构建的列表中选择,也可能存在风险。 我会认真地问自己这(将 SQL 查询的部分内容保存为另一个表中的字符串)是否是最好的方法,但是,如果您决定是的话。 这应该工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.