【问题标题】:SQL - field concatenation, based on variableSQL - 基于变量的字段连接
【发布时间】:2011-04-25 14:21:27
【问题描述】:

我需要根据以下规则从姓氏、名字、中间名首字母构建一个字符串:

  1. 如果姓氏是唯一的,只需 返回姓氏
  2. 如果最后 名称不是唯一的,而是第一个 名字的字母是唯一的, 返回姓氏+第一个字母 名字
  3. 如果姓氏和 名字的第一个字母是 不唯一,返回姓氏+ 名字的第一个字母+中间名 初始。

例如,表格可能是:

   MDC   MDLast      MDFirst     MDInit
    3    Jones       Fred         A    
    21   Smith       Sam          D  
    32   Brown       Tom          E  
    42   Brown       Ted          A  
    55   Smith       Al           D  

查询应该返回:

MDC  MDFormattedName    
3    Jones  
21   Smith S  
32   Brown TE  
42   Brown TA  
55   Smith A  

我编写了一个几乎可以工作的查询,但它使用了多个嵌套查询,并且仍然需要更多的查询来(可能)制定一个可行的解决方案,而且效率很低。我确信有一种“正确”的方式来实现这一点(对于 SQL Server 2005,顺便说一句)。

这是我到目前为止所得到的。它不起作用,由于聚合,我丢失了 ID 无法进行最终连接以获取 ID/名称对。

select 
    CASE
        WHEN CountLastFirst > 1 THEN
            CASE WHEN MDInit IS NOT NULL  THEN MDLastFirst + LEFT(MDInit,1) ELSE MDLastFirst END
        WHEN CountLastFirst = 1 AND CountLast > 1 THEN MDLastFirst
        ELSE MDLast
    END as MDName

FROM

(

select x.MDLast, CountLast, MDLastFirst, CountLastFirst FROM
(
select   MDLast,Count(MDLast) as CountLast FROM
MDList
GROUP BY MDLast) as x

INNER JOIN
(select MDLast,   MDLastFirst,Count(MDLastFirst) as CountLastFirst FROM
(
select MDLast,
MDLast + ' ' + LEFT(MDFirst,1) as MDLastFirst
From MDList
) as a
GROUP BY MDLastFirst, MDLast) as y ON x.MDLast = y.MDLast
) as z

【问题讨论】:

    标签: sql tsql concatenation


    【解决方案1】:

    假设表名为MDCTable,这应该可以工作:

    SELECT MDCTable.MDC,
        CASE MDCCount.NameCount 
        WHEN 1 
        THEN MDCTable.MDLast 
        ELSE    
            CASE MDFormat1Count
            WHEN 1 
            THEN MDFormat1.MDFormat1Name
            ELSE MDCTable.MDLast + ' ' + upper(left(MDCTable.MDFirst, 1)) + 
                      MDCTable.MDInit
            END
        END AS MDFormattedName
    FROM MDCTable 
    INNER JOIN 
    (
        SELECT COUNT(MDLast) as NameCount, MDLast
        FROM MDCTable
        GROUP BY MDLast
    ) MDCCount ON MDCCount.MDLast = MDCTable.MDLast
    INNER JOIN (
        SELECT COUNT(MDLast + left(MDFirst, 1)) as MDFormat1Count, MDLast + ' ' + 
             left(MDFirst, 1) AS MDFormat1Name
        FROM MDCTable
        GROUP BY MDLast + ' ' + left(MDFirst, 1) 
    ) MDFormat1 ON MDCTable.MDLast + ' ' + left(MDCTable.MDFirst, 1) = 
         MDFormat1.MDFormat1Name
    ORDER BY MDCTable.MDC
    

    【讨论】:

    • 非常好,谢谢。我以前从未在 ON 子句中使用过表达式,这是一个很好的技巧。我试图弄清楚如何加入 MDC 索引,但没有明显的方法可以做到这一点。
    【解决方案2】:

    您是否考虑过在您的应用程序中而不是直接在 SQL 语句中执行此操作?除非您有充分的理由直接在 SQL 中执行此操作,否则对于此类情况,这几乎总是更可取的方法。

    【讨论】:

    • 名称列表是从一堆来源访问的,包括存储过程、VB程序、Access查询、SAS程序等。通过在视图中提供它,它一次解决了一堆问题.也许不是最有效的,但重新处理所有这些应用程序是不切实际的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多