我有一個查詢,看起來像這樣:命名的數組變量沒有
select *
from foo
where bar in ("bla", "blub")
and anotherField in ("bla", "blub")
是否有可能命名("bla", "blub")
陣列,並有可能命名爲沒有在一開始使用set
?
我有一個查詢,看起來像這樣:命名的數組變量沒有
select *
from foo
where bar in ("bla", "blub")
and anotherField in ("bla", "blub")
是否有可能命名("bla", "blub")
陣列,並有可能命名爲沒有在一開始使用set
?
的MySQL變量只能保存它的原始數據類型。 MySQL中沒有這樣的數組,也沒有任何將多個值存儲在變量中的功能。
所以,你的問題的簡短答案是「不,這是不可能的」。但是這通常不是什麼大問題,因爲你的應用程序通常使用更高級的語言來構建SQL,在這種語言中你可以很好地在一個變量中保存這樣的集合:因此可以從該變量構建相同的表達式而不必重複自己在很大程度上。這實際上是@NikhilButani's answer通過語句準備完成的。
這就是說,價值的集合可以是SQL表示:畢竟,這正是表是。所以,你可以通過將你的值存儲在表中來解決這個問題。基本上有三種途徑,這是可以實現的,其中沒有一個是比簡單地表達文字的兩個IN()
表達了相同的列表,所以我通常不會建議他們爲你的使用情況「容易」(恕我直言):
創建並填充(可能是暫時的)表,你後來加入到您的查詢:
CREATE TEMPORARY TABLE vals (x VARCHAR(255) NOT NULL PRIMARY KEY);
INSERT INTO vals VALUES ('bla'), ('blub');
SELECT *
FROM foo
JOIN vals v1 ON v1.x = foo.bar
JOIN vals v2 ON v2.x = foo.anotherField;
使用UNION
從子查詢得出「內聯」表:
SELECT *
FROM foo
JOIN (SELECT 'bla' AS x UNION ALL SELECT 'blub') v1 ON v1.x = foo.bar
JOIN (SELECT 'bla' AS x UNION ALL SELECT 'blub') v2 ON v2.x = foo.anotherField;
來自同一UNION
定義視圖,然後加入認爲:
CREATE VIEW vals AS SELECT 'bla' AS x UNION ALL SELECT 'blub';
SELECT *
FROM foo
JOIN vals v1 ON v1.x = foo.bar
JOIN vals v2 ON v2.x = foo.anotherField;
也可以圍繞你的問題與破解MySQL的FIND_IN_SET()
功能,如@Stephan's answer證明。但是,這是一個非常「黑客」,它依賴於具有特定形式的數據,並且不會很好地擴展。
+1的多個解決方案應該工作得更快'FIND_IN_SET()'替代 – Stephan
可惜沒有更簡單的方法。我認爲它可以像'(「bla」,「blub」)[as] NAME'這樣的語法工作,並在第二種情況下使用'NAME'。可惜沒有更簡單的方法...謝謝你:) – Cubinator73
您可以先準備你的SQL
聲明像這樣做:
set @param:="'bla', 'blub'";
SET @sql = CONCAT('SELECT * FROM foo WHERE bar IN (', @param, ')
AND anotherField IN (', @param, ')');
PREPARE stmt FROM @sql;
EXECUTE stmt;
小心妥善轉義'@ param'以防止SQL注入或意外的錯誤。 – eggyal
你可以試試這個:
SELECT 'bla, blub' INTO @mstr;
SELECT
*
FROM
foo
WHERE
find_in_set(bar,@mstr)
AND find_in_set(anotherField,@mstr)
**爲什麼**你想這樣做? – eggyal
因爲我做了一個聊天並且想要選擇兩個用戶的洞對話。因此,發件人必須是UserA或UserB,目標必須是UserA或UserB。而且我不想將這些數組寫兩次。 – Cubinator73
**爲什麼**你不想「編寫這些數組兩次」? – eggyal