簡體   English   中英

SELECT 和 MySQL 中的 CONCAT

[英]SELECT and CONCAT in MySQL

我正在使用 MySQL 並嘗試將 CONCAT_WS() function 與 SELECT 一起使用。

我試過了:

SELECT id, A_12, CONCAT_WS('A_', '12') as testA from TABLE_A

我期待類似的東西

id | A_12 | testA |
-------------------
 1 |  20  |   20  |

testA應該與A_12中的值相同。

但是,我得到的是

id | A_12 | testA |
-------------------
 1 |  20  |   12  |

testA 列中的“12”只是來自 CONCAT_WS() function CONCAT_WS('A_','12')后一個字符串。

任何幫助,將不勝感激。

======編輯======

對不起,我一開始沒有清楚 state 我的問題和目的。 我在 TABLE_A 中有 12 列A_1, A_2, ... , A_12 TABLE_A 更具體地說, Table_A如下所示:

id | A_1 | A_2 | ... | A_12|
---------------------------
 1 |  4  |  5  | ... |  20 |
 2 |  1  |  4  | ... |  50 |
 3 |  2  |  5  | ... |  70 |

我還有另一個表TABLE_B ,看起來像這樣:

id | value
----------
 1 | 12
 2 | 5
 3 | 3

我正在嘗試創建一個存儲的 function ......

  1. select 來自TABLE_B的對應value
  2. TABLE_A中提取A_列下的信息 + 來自Table_B的值

對於每個id

所以我有

SELECT id, CONCAT_WS('A_', stored-value-from-TABLE_B) as testA from TABLE_A

為了確保代碼是否按預期運行,我運行了

SELECT id, A_12, CONCAT_WS('A_', '12') as testA from TABLE_A

因為Table_Bid=1的值為 12。

但是,我得到的是每個idtestA列中的12

很好地得到這個結果只需要

SELECT id, A_12, A_12 as testA from TABLE_A

您似乎認為選擇列表必然是列名列表,因此像 CONCAT_WS() 這樣的字符串 function 會產生像A_12這樣的字符串,並且該字符串必須被解釋為列標識符,因此該查詢的結果將使用該字符串命名的列的值。

但這不是 SQL 選擇列表的工作方式。

選擇列表是表達式列表。 您可以使用一個簡單的列名,結果就是該列中的值。 或者您可以使用另一個表達式,在本例中為字符串 function,結果將是該 function 返回的字符串,而不是名稱恰好與該字符串匹配的列。

正如上面評論中提到的,標識符在 SQL 查詢中是固定的。 您不能創建一個字符串表達式並將該表達式的值解釋為同一查詢中的標識符。 要對標識符進行動態引用,您需要在准備查詢之前使用 SQL 語法對其進行格式化。

您還誤解了CONCAT_WS('A_', '12')作用。 它將其第二個參數和進一步的 arguments 連接起來,第一個參數之間有一個分隔符。 一個典型的用法是:

CONCAT_WS(', ', col1, col2, col3, ...)` 

這將從幾個列的值中返回一個逗號分隔的單詞列表:“value1, value2, value3”。

因此,在您的情況下,您連接了一個值“12”,但分隔符“A_”沒有出現,因為列表中只有一個值。

首先,您不需要CONCAT_WS() ,您想要CONCAT() - 帶分隔符的 Concat 會在所有其他參數之間插入您的第一個參數,並且由於您只有一個其他參數,因此它永遠不會被使用 - 例如CONCAT_WS('A_', '12', '13')會給你12A_13 CONCAT('A_', '12')給你A_12但作為一個字符串,而不是作為列名。

更正為 CONCAT 並進行評估后,您的 select 將如下所示SELECT id, A_12, 'A_12' as testA from TABLE_A; 注意 A_12 周圍的引號。

這是因為 concat 函數返回一個字符串,不能用於按照您想要的方式在 select 字符串中構建列名。 這樣做是可能的,但很復雜——您必須在字符串變量中構建整個查詢字符串,然后將其作為准備好的語句執行:

SET @QueryString = CONCAT('SELECT id, A_12, ', CONCAT('A_', '12'), ' as testA from TABLE_A;');
PREPARE stmnt FROM @QueryString;
EXECUTE stmnt;

嵌套的CONCAT()是不必要的,因為 concat 可以采用任意數量的 arguments 所以你可以將它簡化為:

SET @QueryString = CONCAT('SELECT id, A_12, ', 'A_', '12', ' as testA from TABLE_A;');
PREPARE stmnt FROM @QueryString;
EXECUTE stmnt;

你的 @QueryString 將是SELECT id, A_12, A_12 as testA from TABLE_A;

如果該字符串中的任何內容來自系統中的用戶輸入,這可能會非常危險。 如果它連接到任何應用程序,請使用服務器端應用程序語言使用的任何串聯來組合字符串,然后將其作為查詢執行。

DB Fiddle 測試(SQLFiddle 似乎已經刪除了對准備語句中選擇的支持)

您可以根據id加入表格並選擇合適的A_? 使用 function ELT() ,您必須在其中枚舉所有 12 列:

SELECT b.*, 
       ELT(b.value, a.A_1, a.A_2, ..., a.A_12) testA
FROM TABLE_B b INNER JOIN TABLE_A a
ON b.id = a.id;

查看簡化的演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM