简体   繁体   English

SELECT 和 MySQL 中的 CONCAT

[英]SELECT and CONCAT in MySQL

I'm using MySQL and trying to use CONCAT_WS() function with SELECT.我正在使用 MySQL 并尝试将 CONCAT_WS() function 与 SELECT 一起使用。

I tried:我试过了:

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

I expected something like我期待类似的东西

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

The value is testA should be same as the value in A_12 .testA应该与A_12中的值相同。

However, what I'm getting is但是,我得到的是

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

The '12' in testA column is simply coming from latter string of the CONCAT_WS() function CONCAT_WS('A_','12') . testA 列中的“12”只是来自 CONCAT_WS() function CONCAT_WS('A_','12')后一个字符串。

Any help would be appreciated.任何帮助,将不胜感激。

======EDIT====== : ======编辑======

Sorry I didn't clearly state my question and purpose in the beginning.对不起,我一开始没有清楚 state 我的问题和目的。 I have 12 columns A_1, A_2, ... , A_12 in TABLE_A .我在 TABLE_A 中有 12 列A_1, A_2, ... , A_12 TABLE_A More specifically, Table_A looks like this:更具体地说, Table_A如下所示:

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

I also have another table TABLE_B that looks something like this:我还有另一个表TABLE_B ,看起来像这样:

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

I'm trying to create a stored function that...我正在尝试创建一个存储的 function ......

  1. select the corresponding value from TABLE_B select 来自TABLE_B的对应value
  2. from TABLE_A , pull info under the column A_ + the value from Table_BTABLE_A中提取A_列下的信息 + 来自Table_B的值

for every id .对于每个id

So I have所以我有

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

To make sure if the code is running as I expect, I ran为了确保代码是否按预期运行,我运行了

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

since the value for id=1 in Table_B is 12.因为Table_Bid=1的值为 12。

However, what I'm getting is 12 in testA column for every id .但是,我得到的是每个idtestA列中的12

well to get this result just need很好地得到这个结果只需要

SELECT id, A_12, A_12 as testA from TABLE_A

You seem to think that a select-list is bound to be a list of column names, therefore a string function like CONCAT_WS() would produce a string like A_12 and that string must be interpreted as a column identifier, so the result of that query would use the value of the column named by that string.您似乎认为选择列表必然是列名列表,因此像 CONCAT_WS() 这样的字符串 function 会产生像A_12这样的字符串,并且该字符串必须被解释为列标识符,因此该查询的结果将使用该字符串命名的列的值。

But that's not how an SQL select-list works.但这不是 SQL 选择列表的工作方式。

A select-list is a list of expressions .选择列表是表达式列表。 You could use a simple column name, and the result would be the value in that column.您可以使用一个简单的列名,结果就是该列中的值。 Or you could use another expression, in this case a string function, and the result will be the string returned by that function — not the column that coincidentally has a name matching that string.或者您可以使用另一个表达式,在本例中为字符串 function,结果将是该 function 返回的字符串,而不是名称恰好与该字符串匹配的列。

As mentioned in the comment above, identifiers are fixed in an SQL query.正如上面评论中提到的,标识符在 SQL 查询中是固定的。 You cannot make a string expression and have the value of that expression be interpreted as an identifier in the same query.您不能创建一个字符串表达式并将该表达式的值解释为同一查询中的标识符。 To make a dynamic reference to an identifier, you need to format it in your SQL syntax before you prepare the query.要对标识符进行动态引用,您需要在准备查询之前使用 SQL 语法对其进行格式化。

You also misunderstand what CONCAT_WS('A_', '12') does.您还误解了CONCAT_WS('A_', '12')作用。 It concatenates its 2nd argument and further arguments, with a separator between them of the 1st argument.它将其第二个参数和进一步的 arguments 连接起来,第一个参数之间有一个分隔符。 A typical usage would be:一个典型的用法是:

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

This returns a list of comma-separated words from the values of several columns: "value1, value2, value3".这将从几个列的值中返回一个逗号分隔的单词列表:“value1, value2, value3”。

So in your case, you concatenated a single value "12" but the separator "A_" does not appear because there is only one value in the list.因此,在您的情况下,您连接了一个值“12”,但分隔符“A_”没有出现,因为列表中只有一个值。

First, you don't want CONCAT_WS() , you want CONCAT() - Concat with separator inserts whatever your first argument is between all the others, and since you only have one other argument, it never gets used - for example CONCAT_WS('A_', '12', '13') would give you 12A_13 .首先,您不需要CONCAT_WS() ,您想要CONCAT() - 带分隔符的 Concat 会在所有其他参数之间插入您的第一个参数,并且由于您只有一个其他参数,因此它永远不会被使用 - 例如CONCAT_WS('A_', '12', '13')会给你12A_13 CONCAT('A_', '12') gives you A_12 but as a string, not as a column name. CONCAT('A_', '12')给你A_12但作为一个字符串,而不是作为列名。

After correcting to CONCAT and evaluating, your select will look like this SELECT id, A_12, 'A_12' as testA from TABLE_A;更正为 CONCAT 并进行评估后,您的 select 将如下所示SELECT id, A_12, 'A_12' as testA from TABLE_A; Notice the quotes around A_12.注意 A_12 周围的引号。

This is because concat functions return a string and can't be used to build a column name in a select string the way you want.这是因为 concat 函数返回一个字符串,不能用于按照您想要的方式在 select 字符串中构建列名。 It's possible to do so, but is complicated - you would have to build your entire query string in a string variable then execute it as a prepared statement:这样做是可能的,但很复杂——您必须在字符串变量中构建整个查询字符串,然后将其作为准备好的语句执行:

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

The nested CONCAT() is unnecessary, since concat can take any number of arguments so you get it simplified to this:嵌套的CONCAT()是不必要的,因为 concat 可以采用任意数量的 arguments 所以你可以将它简化为:

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

And your @QueryString will be SELECT id, A_12, A_12 as testA from TABLE_A;你的 @QueryString 将是SELECT id, A_12, A_12 as testA from TABLE_A;

This can be pretty dangerous if anything in that string comes from user input in a system.如果该字符串中的任何内容来自系统中的用户输入,这可能会非常危险。 If this is connected to any application, combine the strings using whatever concatenation your server side application language uses then execute that as a query.如果它连接到任何应用程序,请使用服务器端应用程序语言使用的任何串联来组合字符串,然后将其作为查询执行。

DB Fiddle testing (SQLFiddle seems to have removed support for selects in prepared statements) DB Fiddle 测试(SQLFiddle 似乎已经删除了对准备语句中选择的支持)

You can join the tables on their id s and pick the proper A_?您可以根据id加入表格并选择合适的A_? with the function ELT() where you have to enumerate all 12 columns:使用 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;

See a simplified demo .查看简化的演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM