簡體   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