繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM