SQL中LEFT和RIGHT函数的截取技巧 左右截取字符串的常见用法

LEFT和RIGHT截字,全名拆姓名。

无空格字符串,CASE判断不出错。

中间提取,逗号定位,SUBSTRING截取。

URL域名取,CHARINDEX定位,SUBSTRING截取。

索引优化,WHERE改LIKE,效率高。

你自己掂量。

sql截取某个字符之前的数据

嗯,我昨天帮邻居老王整理电脑里的照片,他那个硬盘塞得满满当当。
他特别着急找一张去年夏天去黄山拍的照片,结果找了半天,最后发现那张照片的名字是“黄山日出_2 02 3 -08 -1 5 .jpg”。
他当时就说了,要是能快速找到名字里带“黄山”的就好了。

这不,我正好在琢磨SQL的事,想着用这个SUBSTRING函数,确实挺实用的。
假设老王的照片都在一个叫Photos的表里,照片的名字存放在FileName这一列。
那要找到所有名字里包含“黄山”的照片,就可以用你说的这个方法。
比如,我要找“黄山日出”这部分,可以写成:
sql SELECT FileName FROM Photos WHERE SUBSTRING(FileName, 1 , CHARINDEX('黄山', FileName)
1 ) = '黄山'
这个查询会返回所有名字里“黄山”在第一个位置的照片名字。
比如“黄山日出_2 02 3 -08 -1 5 .jpg”,它就会匹配上。
如果老王是想找所有名字里带“黄山”的,不管它出现在哪个位置,那就可以稍微改动一下:
sql SELECT FileName FROM Photos WHERE FileName LIKE '%黄山%'
这样不管“黄山”出现在名字的哪个位置,只要名字里有“黄山”,它都会被找出来。
这倒是挺方便的,对吧?
等等,还有个事。
我刚才试了一下,发现如果名字里没有“黄山”,比如“泰山日出_2 02 3 -08 -1 6 .jpg”,那CHARINDEX函数会返回0,所以SUBSTRING函数的长度就会是-1 ,这肯定会出错的。
所以,在写SQL查询的时候,还得考虑这些特殊情况,不然有时候结果会跟你预期的不一样。
比如,可以这样写:
sql SELECT FileName FROM Photos WHERE CHARINDEX('黄山', FileName) > 0
这样就能确保只有名字里真的有“黄山”的时候,才会返回结果。
你看,这些小细节还挺重要的。

我突然想到,如果老王的照片名字里还有其他分隔符,比如用“_”或者“-”分隔,那是不是可以用类似的方法来截取前面的一部分?比如“黄山_日出_2 02 3 -08 -1 5 .jpg”,我想截取“黄山”这部分,就可以用:
sql SELECT SUBSTRING(FileName, 1 , CHARINDEX('_', FileName)
1 ) AS PartBeforeDelimiter FROM Photos
这样就能截取到第一个“_”之前的部分。
如果名字里只有“黄山”一个词,没有其他分隔符,那CHARINDEX函数会返回0,SUBSTRING函数的长度还是-1 ,这时候就需要再加个条件来处理这种情况。
比如:
sql SELECT SUBSTRING(FileName, 1 , CHARINDEX('_', FileName)
1 ) AS PartBeforeDelimiter FROM Photos WHERE FileName LIKE '黄山%' OR CHARINDEX('_', FileName) = 0
这样就能确保只有名字里只有“黄山”或者有“_”的时候,才会截取前面的部分。
你看,这些小细节有时候还挺费脑子的。

对了,你刚才说CHARINDEX函数会返回0,那如果返回的是1 呢?比如“_黄山日出_2 02 3 -08 -1 5 .jpg”,这时候SUBSTRING函数的长度就是0,截取的结果就是空字符串。
所以,有时候还得再加个条件来排除这些情况。
比如:
sql SELECT SUBSTRING(FileName, 1 , CHARINDEX('_', FileName)
1 ) AS PartBeforeDelimiter FROM Photos WHERE CHARINDEX('_', FileName) > 1
这样就能确保只有名字里“_”不是第一个字符的时候,才会截取前面的部分。
你看,这些小细节有时候还挺重要的。

你还有什么想说的吗?

SQL 字符串函数如何截取最后几位?

RIGHT函数最简单。
直接用就行。

数据库不一样,方法有区别。
MySQL、SQLServer、Oracle都支持RIGHT。

PostgreSQL、SQLite得用SUBSTRING+LEN。

Oracle用SUBSTR(-n)倒数截取。

注意空值处理。
长度不够就返回NULL。

怎么选?看用哪个数据库就用什么方法。

字段为空咋办?你想想。

SQL 字符串函数如何截取子串?

说实话,这SQL截取字符串的玩意儿,用多了也就那么回事儿。
SUBSTRING啊,SUBSTR啊,说白了就是从哪儿开始剪,剪多长。

一般都用这个公式:SUBSTRING(字符串啊,从第几个字开始啊,剪多少个字)。
字符串就是你要剪的原材料,从第几个字开始,多数是从1 开始数,别跟Python似的从0开始瞎搞。
剪多少个字,这个可以不写,不写的话就剪到头。

像MySQL啊,PostgreSQL啊,SQL Server啊,它们都认SUBSTRING这个函数。
Oracle和SQLite那边,它们叫SUBSTR,其实干的事儿一样。

举个例子,剪'HelloWorld'这个字符串,从第7 个字开始剪5 个字,那就是'World'。
如果你剪到头,长度就不写了,就剪从第2 个字开始到尾巴。

有时候要剪点特别的东西,比如剪邮箱用户名,或者剪文件后缀名。
剪邮箱用户名,得先找到'@'在哪儿,用CHARINDEX或者INSTR这俩函数找。
比如SQL Server这边,先用CHARINDEX找到'@'的位置,然后从第1 个字开始剪,剪到'@'前面一个字结束。
Oracle和MySQL那边,就用INSTR代替CHARINDEX。

剪文件后缀名,假设文件名是filename,你想剪最后4 个字,比如'.txt'。
SQL Server这边,可以用LEN函数算出总长,然后剪从倒数第4 个字开始。
更通用的方法,是用CASE WHEN判断有没有'.',有'.'就从倒数第4 个字开始剪,没有'.'就从第1 个字开始剪。

注意事项就那么几个:从1 开始数位置,不写长度就剪到头,位置超过字符串长度就返回空,长度超过剩下的字数就剪到头。
数据库之间有点小差异,比如Oracle的SUBSTR能接受负数位置,SQL Server就不行,用之前得查查文档。

总之,这玩意儿不难,就是得知道从哪儿剪,剪多长。
剪邮箱啊,剪后缀名啊,都能用。
不过不同数据库之间得注意点差异,别搞错了。