2014-03-03 83 views
0

我有一個查詢,看起來像這樣:命名的數組變量沒有

select * 
from foo 
where bar in ("bla", "blub") 
and anotherField in ("bla", "blub") 

是否有可能命名("bla", "blub")陣列,並有可能命名爲沒有在一開始使用set

+1

**爲什麼**你想這樣做? – eggyal

+0

因爲我做了一個聊天並且想要選擇兩個用戶的洞對話。因此,發件人必須是UserA或UserB,目標必須是UserA或UserB。而且我不想將這些數組寫兩次。 – Cubinator73

+0

**爲什麼**你不想「編寫這些數組兩次」? – eggyal

回答

2

的MySQL變量只能保存它的原始數據類型。 MySQL中沒有這樣的數組,也沒有任何將多個值存儲在變量中的功能。

所以,你的問題的簡短答案是「不,這是不可能的」。但是這通常不是什麼大問題,因爲你的應用程序通常使用更高級的語言來構建SQL,在這種語言中你可以很好地在一個變量中保存這樣的集合:因此可以從該變量構建相同的表達式而不必重複自己在很大程度上。這實際上是@NikhilButani's answer通過語句準備完成的。

這就是說,價值的集合可以是SQL表示:畢竟,這正是是。所以,你可以通過將你的值存儲在表中來解決這個問題。基本上有三種途徑,這是可以實現的,其中沒有一個是比簡單地表達文字的兩個IN()表達了相同的列表,所以我通常不會建議他們爲你的使用情況「容易」(恕我直言):

  1. 創建並填充(可能是暫時的)表,你後來加入到您的查詢:

    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; 
    
  2. 使用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; 
    
  3. 來自同一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證明。但是,這是一個非常「黑客」,它依賴於具有特定形式的數據,並且不會很好地擴展。

+0

+1的多個解決方案應該工作得更快'FIND_IN_SET()'替代 – Stephan

+0

可惜沒有更簡單的方法。我認爲它可以像'(「bla」,「blub」)[as] NAME'這樣的語法工作,並在第二種情況下使用'NAME'。可惜沒有更簡單的方法...謝謝你:) – Cubinator73

1

您可以先準備你的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; 
+0

小心妥善轉義'@ param'以防止SQL注入或意外的錯誤。 – eggyal

1

你可以試試這個:

SELECT 'bla, blub' INTO @mstr; 

SELECT 
    * 
FROM 
    foo 
WHERE 
    find_in_set(bar,@mstr) 
    AND find_in_set(anotherField,@mstr) 
+1

你是不是指'WHERE FIND_IN_SET(bar,@ mstr)和FIND_IN_SET(anotherField,@mstr)'?請注意,如果'bar','anotherField'或'@ mstr'中的值本身包含逗號字符,這將不起作用。另外,請注意,這種方法效率非常低,因爲它要求對每個記錄執行字符串匹配的全表掃描。 – eggyal

+0

另外,'@ mstr'應該只包含''bla,blub''。 – eggyal

+0

@eggyal你的權利:D thx虐待它現在更新它 – Stephan