如何在SQL中拆分和显示单词中的不同字母?

Str*_*der 13 sql

昨天在求职面试中,我被问到这个问题,我对此一无所知.假设我有一个单词"Manhattan"我想在SQL中只显示字母'M','A','N','H','T'.怎么做?任何帮助表示赞赏.

use*_*740 12

好吧,这是我的解决方案(sqlfiddle) - 它的目的是使用"关系SQL"操作,这可能是面试官在概念上的用途.

完成的大部分工作只是将字符串转换为一组(pos,letter)记录,因为相关的最终应用DQL仅仅是应用了分组和排序的SELECT.

select letter
from (
  -- All of this just to get a set of (pos, letter)
  select ns.n as pos, substring(ss.s, ns.n, 1) as letter
  from (select 'MANHATTAN' as s) as ss
  cross join (
    -- Or use another form to create a "numbers table"
    select n from (values (1),(2),(3),(4),(5),(6),(7),(8),(9)) as X(n)
    ) as ns
  ) as pairs
group by letter    -- guarantees distinctness
order by min(pos)  -- ensure output is ordered MANHT
Run Code Online (Sandbox Code Playgroud)

上述查询适用于SQL Server 2008,但可能必须为其他供应商更改"Numbers表".否则,没有使用特定于供应商的任何东西 - 没有CTE,或函数的交叉应用,或程序语言代码.

话虽如此,上面的内容是为了展示一种概念方法 - SQL被设计用于集合和关系以及跨记录的多重性; 在某种意义上,上述例子仅仅是对此类的歪曲.


检查中间关系,

  select ns.n as pos, substring(ss.s, ns.n, 1) as letter
  from (select 'MANHATTAN' as s) as ss
  cross join (
    select n from (values (1),(2),(3),(4),(5),(6),(7),(8),(9)) as X(n)
    ) as ns
Run Code Online (Sandbox Code Playgroud)

使用交叉连接生成字符串(1行)的笛卡尔积和数字(9行); substring然后将该函数与字符串和每个数字一起应用,以根据其位置获得每个字符.结果集包含记录 -

POS LETTER
1   M
2   A
3   N
..
9   N
Run Code Online (Sandbox Code Playgroud)

然后外部选择组根据字母记录每个记录,并且结果记录按建立分组的字母的最小(第一)发生位置排序.(没有字母的顺序会有所不同,但最终的顺序不会得到保证.)


hat*_*ica 7

一种方法(如果使用SQL Server)使用递归CTE(Commom Table Expression).

DECLARE @source nvarchar(100) = 'MANHATTAN'
;
WITH cte AS (
    SELECT SUBSTRING(@source, 1, 1) AS c1, 1 as Pos
    WHERE LEN(@source) > 0
    UNION ALL
    SELECT SUBSTRING(@source, Pos + 1, 1) AS c1, Pos + 1 as Pos
    FROM cte
    WHERE Pos < LEN(@source)
)
SELECT DISTINCT c1 from cte
Run Code Online (Sandbox Code Playgroud)

SqlFiddle就在这里.我不得不内联@source为SqlFiddle,但上面的代码在Sql Server中工作正常.

第一SELECT行生成初始行(在本例中为"M",1).第二个SELECT是生成后续行的递归部分,Pos每次都会增加列,直到WHERE Pos < LEN(@source)最终满足终止条件.最终选择删除重复项.在内部,SELECT DISTINCT对行进行排序以便于删除重复项,这就是为什么最终输出恰好按字母顺序排列的原因.由于您没有将订单指定为要求,因此我将其保留为原样.但是你可以修改它以使用一个GROUP代替,MIN(Pos)如果你需要输出字符的原始顺序,那就命令.

同样的技术可以用于生成字符串的所有Bigrams之类的事情,只需对上面的一般结构进行一些小改动.