[英]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 ......
TABLE_B
的对应value
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_B
中id=1
的值为 12。
但是,我得到的是每个id
的testA
列中的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 似乎已经删除了对准备语句中选择的支持)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.