在SQL Server和Oracle SQL中如何根据固定字符选择第n个空间的子字符串

在SQL Server和Oracle SQL中如何根据固定字符选择第n个空间的子字符串,sql,sql-server,regex,oracle,Sql,Sql Server,Regex,Oracle,我需要根据固定字符长度选择一个子字符串,直到第n个空格。让我解释一下这个问题 假设我有三个不同的字符串: Lorem ipsum dolor sit amet,献祭精英 Lorem ipsumdolor sit amet,奉献精英 Lorem ipsum Dolorisitamet,献身精英 如果我从字符串的开头选择20个字符,我将按顺序获得以下子字符串 同侧耳 洛雷姆·伊普苏姆多洛 同侧耳 但是我想要我的子字符串,它最多20个字符长,就像这样 同侧阴唇 洛雷姆·伊普苏姆多洛 乱数假文 也就是说

我需要根据固定字符长度选择一个子字符串,直到第n个空格。让我解释一下这个问题

假设我有三个不同的字符串:

Lorem ipsum dolor sit amet,献祭精英 Lorem ipsumdolor sit amet,奉献精英 Lorem ipsum Dolorisitamet,献身精英 如果我从字符串的开头选择20个字符,我将按顺序获得以下子字符串

同侧耳 洛雷姆·伊普苏姆多洛 同侧耳 但是我想要我的子字符串,它最多20个字符长,就像这样

同侧阴唇 洛雷姆·伊普苏姆多洛 乱数假文 也就是说,我不希望在两个空格之间有任何部分单词

请帮助我生成查询。

Oracle:

select substr(substr(MyField,1,20), 1, instr(substr(MyField,1,20), ' ',-1,1))
from MyTable
SQL Server

SELECT LEFT(MyField, 20 - CHARINDEX (' ' ,REVERSE(LEFT(MyField,20))))
FROM MyTable

如果是SQL Server,如果您不介意自定义项

Declare @YourTable table (SomeText varchar(500))
Insert Into @YourTable values
('Lorem ipsum dolor sit amet, consectetur adipiscing elit.'),
('Lorem ipsumdolor sit amet, consectetur adipiscing elit'),
('Lorem ipsum dolorsitamet, consectetur adipiscing elit')

Declare @MaxLen int = 20
Select *,Trimmed = [dbo].[udf-Str-TrimToWord](SomeText,@MaxLen)
 From  @YourTable
返回

SomeText                                                    Trimmed
Lorem ipsum dolor sit amet, consectetur adipiscing elit.    Lorem ipsum dolor
Lorem ipsumdolor sit amet, consectetur adipiscing elit      Lorem ipsumdolor
Lorem ipsum dolorsitamet, consectetur adipiscing elit       Lorem ipsum
UDF

CREATE FUNCTION [dbo].[udf-Str-TrimToWord] (@String varchar(max),@MaxLen int)
Returns varchar(max)
AS
Begin
    Return LEFT(@String,@MaxLen-CharIndex(' ' ,Reverse(Left(@String,@MaxLen))))
End

对于Oracle,应该可以将其转换为SQL Server,但我不知道SQL Server:

如果第一个空格前的第一个标记超过20个字符,则返回NULL 如果第21个字符是空格,则返回前20个字符 如果第21个字符不是空格,但前20个字符之间有空格,则删掉前20个字符,然后找到最后一个空格并删除它及其后的所有内容。 如果整个字符串最多为20个字符,则应按原样返回。 在下面的测试数据中,我又添加了两个示例,以测试这是否能够按需要工作

with
     inputs ( str ) as (
       select 'Lorem ipsum dolor sit amet, consectetur adipiscing elit' from dual union all
       select 'Lorem ipsumdolor sit amet, consectetur adipiscing elit'  from dual union all
       select 'Loremipsumdolorsitametconsedtetur'                       from dual union all
       select 'Lorem ipsumdolorsit amet, consectetur etc.'              from dual union all
       select 'Lorem ipsum dolorsitamet, consectetur adipiscing elit'   from dual union all
       select 'abcdef ghijk lmno'                                       from dual
     ),
     prep ( str, flag, fragment ) as (
       select str, 
              case when length(str) <= 20 or substr(str, 21, 1) = ' ' then 1 end, 
              substr(str, 1, 20)
       from   inputs
     )
select str, 
       case flag when 1 then fragment 
                        else substr(fragment, 1, instr(fragment, ' ', -1) - 1) end
       as new_str
from   prep;

STR                                                     NEW_STR            
------------------------------------------------------- --------------------
Lorem ipsum dolor sit amet, consectetur adipiscing elit Lorem ipsum dolor   
Lorem ipsumdolor sit amet, consectetur adipiscing elit  Lorem ipsumdolor sit
Loremipsumdolorsitametconsedtetur                                           
Lorem ipsumdolorsit amet, consectetur etc.              Lorem ipsumdolorsit 
Lorem ipsum dolorsitamet, consectetur adipiscing elit   Lorem ipsum
abcdef ghijk lmno                                       abcdef ghijk lmno 

如果第21个字符是空格,则结果应为前20个字符。此解决方案不检查该问题;它返回的字符少于20个。对于Oracle:如果输入字符串类似于“abcdef ghijk lmno”,该如何处理。查询应返回整个字符串。如果输入字符串类似于“abcdef ghijk lmno”,该如何处理。查询应该返回整个stringGood问题,我没有考虑过这种情况,可以肯定的是,它没有涵盖我得到了错误的输出。我需要修改一下代码,我会在下一分钟编辑。谢谢