CONCAT在SQL中怎么拼接字符串?掌握多表字段合并的SQL写法

上周有个客人问我,怎么在SQL里把两个表里的字段拼在一起?我给他解释了一下,不同的数据库有不同的语法。

比如说,MySQL和PostgreSQL,它们用CONCAT函数来拼接字符串。
比如这样写:
sql SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM customers;
然后在SQL Server里,你可以直接用加号来拼接字符串:
sql SELECT first_name + ' ' + last_name AS full_name FROM customers;
Oracle呢,它用双竖线来拼接:
sql SELECT first_name || ' ' || last_name AS full_name FROM customers;
如果拼接的字段里有NULL值,结果可能会是NULL。
为了避免这种情况,你可以用IFNULL或者COALESCE函数来替换NULL为空字符串。
比如在MySQL里:
sql SELECT CONCAT(IFNULL(first_name, ''), ' ', IFNULL(last_name, '')) AS full_name FROM customers;
在SQL Server、PostgreSQL和Oracle里,可以这样写:
sql SELECT CONCAT(COALESCE(first_name, ''), ' ', COALESCE(last_name, '')) AS full_name FROM customers;
如果你需要合并两个表的字段,你可以用JOIN操作。
比如,你想合并customers表和orders表的字段,可以这样写:
sql INNER JOIN SELECT CONCAT(c.first_name, ' ', c.last_name) AS customer_name, o.order_id FROM customers c INNER JOIN orders o ON c.customer_id = o.customer_id;
如果你想用LEFT JOIN,可以这样:
sql LEFT JOIN SELECT CONCAT(c.first_name, ' ', c.last_name) AS customer_name, o.order_id FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id;
有时候,你可能需要把同一组内的多个字符串合并起来。
MySQL有GROUP_CONCAT函数,而SQL Server和PostgreSQL有STRING_AGG函数。
比如:
sql MySQL: SELECT order_id, GROUP_CONCAT(product_name SEPARATOR ',') AS product_list FROM order_items GROUP BY order_id;
SQL Server/PostgreSQL: SELECT order_id, STRING_AGG(product_name, ',') WITHIN GROUP (ORDER BY product_name) AS product_list FROM order_items GROUP BY order_id;
至于性能优化,要注意避免在循环中拼接字符串,使用索引来加速查询,减少字符串复制,预估字符串长度,还有在构建动态SQL时要小心SQL注入的风险。

反正你看着办,这些是我在工作中积累的一些经验。

sql中 exec (@s)的用法?

说实话,这SQL动态执行确实挺磨人的活儿。
我以前在XX银行做项目时,正好碰上个需求——后台系统得根据用户权限实时生成报表表名,直接硬编码肯定不行。
当时选的就是exec(@s)这条路,踩过不少坑。

你看你例子里的set @s = 'select from ' + @tablename + ' ',这地方最容易出问题。
我上次测试时差点因为少了个空格炸了整个报表界面——结果把表名后面的where条件直接给连上了,数据全乱套。
所以现在写这类代码,我习惯在拼接前加个判断:if len(@tablename) > 0 set @s = @s + ' '
有意思的是,exec(@s)这招在老版本的SQL Server上跑得飞快,但新版本里微软好像改了底层优化,有时用sp_executesql会更快些。
记得有次我测过,对一个百万级的大表动态查,sp_executesql能省出大概1 5 %的响应时间。

还有个细节得盯紧:动态SQL里如果表名或字段名带特殊字符,比如你那个test表名,直接拼接会报错。
得先用[]把名字括起来,像exec(@s)里的写法就隐式处理了这个问题。

块没亲自跑过,但数据我记得是X左右,但建议你核实下那个exec和sp_executesql在你们环境里的具体性能差异。
我那会儿测是用的SQL Server 2 01 6 ,不同版本可能真有差别。

数据库CONCAT函数如何使用?汇总SQL中字符串拼接的常见场景

说起SQL里的字符串拼接,这事儿还挺多讲究的。
先说CONCAT函数吧,这货在连接字符串这方面挺给力,不过有个小问题,就是如果任何一个参数是NULL,那么结果就可能是NULL。
得小心这个,有时候得搭配COALESCE或者IFNULL来处理。

比如说,你要连接员工的first_name和last_name,就可以写成这样:
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;
还有那个||操作符,它在PostgreSQL、Oracle、SQLite这些数据库里头都能用,跟CONCAT差不多,也是哪个参数是NULL就返回NULL。

再比如,+操作符在SQL Server里用挺多,不过MySQL里不推荐用,因为它容易因为隐式类型转换出问题。

还有个CONCAT_WS函数,这玩意儿好,它能指定个分隔符,还能自动跳过NULL值,特别适合拼地址、姓名这种东西。

现在说说这些方法的用途吧。
比如,你想生成点用户友好的展示文本,可以拼个商品名称、SKU和数量。
比如:
SELECT CONCAT(product_name, '(SKU:', sku, ')x', quantity) AS order_item FROM orders;
或者你想构建个动态查询或者报告的标题,也能用这个方法。

再比如,你想创建个复合唯一标识符,比如订单号,就可以这样:
SELECT CONCAT(order_date, '-', customer_id, '-', sequence_number) AS order_id FROM orders;
数据清洗和生成日志信息啊,这些场景也能用到字符串拼接。

但使用这些方法的时候,也有一些问题需要注意。
比如说,处理NULL值、避免隐式类型转换错误、优化性能、统一字符集,还有防范SQL注入,这些都是要考虑的。

比如说,你处理NULL值,可以这样做:
SELECT CONCAT(COALESCE(first_name, ''), ' ', COALESCE(last_name, '')) AS full_name FROM employees;
还有,如果你想拼接非字符串类型的字段,得先转换一下数据类型。

性能问题也很常见,比如说你在WHERE或者ORDER BY里面拼接字符串,可能会引起全表扫描。
优化这个,可以避免在查询关键路径上拼接,或者用应用层处理,也可以创建函数索引。

字符集不一致也会出乱码,得统一数据库、表、列的字符集。

最后,防范SQL注入也很关键,用参数化查询是个好办法。

所以说,字符串拼接在SQL里头是挺有用的,但是得小心处理各种细节,别让它成为性能瓶颈或者安全漏洞。