【问题标题】:What's the shortest TSQL to concatenate a person's name which may contain nulls连接可能包含空值的人名的最短 TSQL 是什么
【发布时间】:2008-12-08 23:37:39
【问题描述】:

3 个字段:名字、中间名、姓氏

任何字段都可以为空,但我不想要额外的空格。格式应为“First Middle Last”、“First Last”、“Last”等。

【问题讨论】:

  • 我认为问题应该指定inline SQL。否则,您可以像提到的答案之一那样做一个单字符触发。

标签: sql sql-server tsql


【解决方案1】:
    LTRIM(RTRIM(
    LTRIM(RTRIM(ISNULL(FirstName, ''))) + ' ' + 
    LTRIM(RTRIM(ISNULL(MiddleName, ''))) + ' ' + 
    LTRIM(ISNULL(LastName, ''))
    ))

注意:这不会留下尾随或前导空格。这就是为什么它比其他解决方案有点丑。

【讨论】:

  • 我很想知道(说真的!)为什么这没有帮助......也许反对者可以启发我?它实际上完全按照要求工作,涵盖了所有极端情况。
  • 安德鲁,我真的很讨厌这种情况发生。请为 uservoice 投票以进行更改:stackoverflow.uservoice.com/pages/general/suggestions/41056
  • 是的。考虑到其他两种解决方案实际上并没有按照要求做......嗯,我猜这只是我的酸葡萄。不过,我希望看到一些问责制:(
  • 在没有MiddleName的情况下不中间留双空格吗?可能需要围绕整个事物进行空间减少替换。什么的。
  • 嗨安德鲁,有趣的是,你的答案不是我投反对票的答案! Charles Bretana 的答案的早期版本是我反对的版本(他使用了 TRIM,这不是公认的 TSQL 函数 - 请参阅我的 cmets 到他的帖子!)。也许是一个错误?无论如何,我已经删除了对你答案的不正确的否决票。
【解决方案2】:

假设“额外空格”是指在连接期间插入的额外空格(我认为这是一个合理的假设。如果您的数据中有额外的空格,则应该清理它):

ISNULL(FirstName + ' ', '')  + ISNULL(MiddleName + ' ', '') + ISNULL(LastName, '')

有效,因为您将在名称中添加一个空格 - 如果它为 NULL,则生成 NULL - 这将生成空字符串。

编辑:如果您不计算 SET OPTION - 它可以是连接或数据库选项:

SET CONCAT_NULL_YIELDS_NULL OFF
LTRIM(FirstName + ' ' + NULLIF(MiddleName + ' ', ' ') + LastName)

短了一点,但丑了一大截。

Edit2:既然您接受了 UDF 答案 - IMO,这有点作弊 - 这里有一些相同的内容:

SELECT a FROM b

b 是一个视图。 ;) 或者。一个存储过程,

EXEC c

但是,由于 EXEC 是可选的:

c

【讨论】:

  • 我选择了 UDF,因为它是最短的实用解决方案。我可能会使用你的(预编辑)解决方案而不是 UDF,所以我给你投了赞成票。
  • +1 这是最好/最短的答案,完全符合 OP 的要求。
【解决方案3】:

使用 UDF:

`Select udfConcatName(First, Middle, Last) from foo`

这样你所有的名字连接逻辑都在一个地方,一旦你把它写下来,调用起来很简单。

【讨论】:

  • 除非您将其设为“内联”udf,否则这将对性能产生不利影响,因为 udf(内联类型除外)会在每次执行时重新编译。所以它们可以一次性使用,在单行选择中。或填充变量 b4 多行选择,但不是在多行选择的每一行上
  • 好悲痛。同意。如果你必须使用大量的值,这将像糖蜜一样慢。
【解决方案4】:
LTRIM(RTRIM(ISNULL(FirstName, '') + ' ' + LTRIM(ISNULL(MiddleName, '') + ' ' + 
    ISNULL(LastName, ''))))

【讨论】:

  • 请注意,这会在中间名和姓氏之间留下额外的空格(如果中间名末尾有空格),也会在姓氏之后(如果结尾有空格) .
【解决方案5】:

为什么不在表上使用计算列,使用此处发布的许多您喜欢的语法为您执行连接?然后您将只查询计算列 - 非常优雅,如果您保留计算列,那么您甚至可能会获得轻微的性能提升。 Example here

【讨论】:

    【解决方案6】:
    replace(ltrim(rtrim(isnull(FirstName, '') + ' ' + isnull(MiddleName, '') + ' ' + isnull(LastName, ''))), '  ', ' ')
    

    【讨论】:

      【解决方案7】:
      '"' + ltrim(rtrim(isnull(FirstName,''))) + ' ' + ltrim(rtrim(isnull(MiddleName,''))) + 
      ' ' + ltrim(rtrim(isnull(LastName,''))) + '","' + ltrim(rtrim(isnull(FirstName,''))) + 
      ' ' + ltrim(rtrim(isnull(LastName,''))) + '","' + ltrim(rtrim(isnull(LastName,''))) + 
      '"'
      

      ETC

      【讨论】:

        【解决方案8】:
        DECLARE @first varchar(10) = 'First'
        DECLARE @middle varchar(10) = ''
        DECLARE @last varchar(10) = 'Last'
        
        LTRIM(RTRIM(
            @first
            + ISNULL(NULLIF(' '+LTRIM(RTRIM(@middle)),' '),'')
            + ISNULL(NULLIF(' '+LTRIM(RTRIM(@last)),' '),'')
        ))
        

        为什么会这样

        如果为 NULL 或空格,LTRIM、RTRIM 和 ISNULL 函数会将字段缩减为空字符串。

        LTRIM(RTRIM(ISNULL(@middle,''))) -- Result is a trimmed non-null string value.
        

        该值以单个空格为前缀,然后由 NULLIF 函数与单个空格进行比较。如果相等,则结果为 NULL。如果不相等,则使用该值。

        NULLIF(' '+'',' ')       -- this would return NULL
        NULLIF(' '+'Smith',' ')  -- this would return ' Smith'
        

        最后,ISNULL()用于将NULLIF传递的NULL转换为空字符串。

        ISNULL(NULL,'')          -- this would return ''
        ISNULL(' Smith','')      -- this would return ' Smith'
        

        【讨论】:

          【解决方案9】:

          LTrim(RTrim(Replace(IsNull(Firstname + ' ', '') + isNull(MiddleName, '') + IsNull(' ' + LastName, ''), ' ', ' ')))

          【讨论】:

          • TRIM 不是 TSQL 中公认的内置函数名称
          • 啊,对不起,应该写 Ltrim(rtrim(...))
          【解决方案10】:
          Select firstname, middlename, lastname, ProvidedName = 
          
          RTrim(Coalesce(FirstName + ' ','') 
          + Coalesce(MiddleName + ' ', '')
          + Coalesce(LastName + ' ', '')
          + COALESCE('' + ' ', '')
          + COALESCE(NULL, ''))
          
          From names
          

          【讨论】:

            猜你喜欢
            • 2023-02-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-02-13
            相关资源
            最近更新 更多