我有一个名为WORDS的表,如下所示:
------------------------------
Symbol ParentSymbol
------------------------------
a
ab
abc
abd
abda
abdb
b
ba
bb
bbbc
bbc
abcd
bbbbbbbbbbbbba
我想像这样更新ParentSymbol列:
------------------------------
Symbol ParentSymbol
------------------------------
a
ab a
abc ab
abd ab
abda abd
abdb abd
b
ba b
bb b
bbbc bb
bbc bb
abcd abc
bbbbbbbbbbbbba bb
------------------------------
ParentSymbol
列仅包含“符号列”中的值,如果未找到父项,则为null。
我正在考虑基于Symbol的子字符串进行分区的某种联接,但是我不知道如何。
有什么办法可以做到这一点?
答案 0 :(得分:3)
ParentSymbol仅少一个字母吗?
UPDATE w
SET ParentSymbol = left(Symbol, len(Symbol) - 1)
FROM WORDS w
更新的查询
UPDATE w
SET ParentSymbol = ISNULL(p.ParentSymbol, '')
FROM WORDS w
OUTER APPLY
(
SELECT TOP 1 ParentSymbol = x.Symbol
FROM WORDS x
WHERE x.Symbol <> w.Symbol
AND w.Symbol LIKE x.Symbol + '%'
ORDER BY x.Symbol DESC
) p
答案 1 :(得分:1)
以下代码首先找到与该值最接近的一个作为子字符串。
/*
create table #words (Symbol varchar(100), ParentSymbol varchar(100));
insert into #words (Symbol) values ('a')
insert into #words (Symbol) values ('ab')
insert into #words (Symbol) values ('abc')
insert into #words (Symbol) values ('abd')
insert into #words (Symbol) values ('abda')
insert into #words (Symbol) values ('abdb')
insert into #words (Symbol) values ('b')
insert into #words (Symbol) values ('ba')
insert into #words (Symbol) values ('bb')
insert into #words (Symbol) values ('bbbc')
insert into #words (Symbol) values ('bbc')
insert into #words (Symbol) values ('abcd')
*/
with cte as(
select w2.Symbol as ChildSymbol,
max(w.Symbol) as Symbol
from #words as w
inner join #words as w2 ON w.Symbol <> w2.Symbol and charindex(w.Symbol,w2.Symbol) = 1
group by w2.Symbol
)
select w.Symbol,
c.Symbol as ParentSymbol
from #words as w
left outer join cte as c ON w.Symbol = c.ChildSymbol
答案 2 :(得分:0)
我尝试使用dense_rank
和row_number
窗口函数。
第二次尝试-
declare @table table (Symbol varchar(10));
insert into @table values
('a')
,('ab')
,('abc')
,('abd')
,('abda')
,('abdb')
,('b')
,('ba')
,('bb')
,('bbbc')
,('bbc')
,('abcd');
;with cte as (
select left(symbol, 1) as FirstSymbol
from @table
group by left(symbol, 1)
),
cte2 as (
select *, ROW_NUMBER() over (partition by b.firstSymbol order by a.symbol) as RankInGroup
from @table as a
left join cte as b on left(a.Symbol, 1) = b.FirstSymbol
)
select a.Symbol as Symbol, b.Symbol as ParentSymbol
from cte2 as a
left join cte2 as b on a.FirstSymbol = b.FirstSymbol and a.RankInGroup = b.RankInGroup + 1;
第一次尝试-
declare @table table (Symbol varchar(10));
insert into @table values
('a')
,('ab')
,('abc')
,('abd')
,('abda')
,('abdb')
,('b')
,('ba')
,('bb')
,('bbbc')
,('bbc')
,('abcd');
--select * from @table;
;with cte as (
select
symbol,
dense_rank() over (
order by (
case
when symbol like 'a%' then 1 when symbol like 'b%' then 2 when symbol like 'c%' then 3 when symbol like 'd%' then 4
when symbol like 'e%' then 5 when symbol like 'f%' then 6 when symbol like 'g%' then 7 when symbol like 'h%' then 8
when symbol like 'i%' then 9 when symbol like 'j%' then 10 when symbol like 'k%' then 11 when symbol like 'l%' then 12
when symbol like 'm%' then 13 when symbol like 'n%' then 14 when symbol like 'o%' then 15 when symbol like 'p%' then 16
when symbol like 'q%' then 17 when symbol like 'r%' then 18 when symbol like 's%' then 19 when symbol like 't%' then 20
when symbol like 'u%' then 21 when symbol like 'v%' then 22 when symbol like 'w%' then 23 when symbol like 'x%' then 24
when symbol like 'y%' then 25 when symbol like 'z%' then 26
end)
) as GroupNumber,
row_number() over (
partition by (
case
when symbol like 'a%' then 1 when symbol like 'b%' then 2 when symbol like 'c%' then 3 when symbol like 'd%' then 4
when symbol like 'e%' then 5 when symbol like 'f%' then 6 when symbol like 'g%' then 7 when symbol like 'h%' then 8
when symbol like 'i%' then 9 when symbol like 'j%' then 10 when symbol like 'k%' then 11 when symbol like 'l%' then 12
when symbol like 'm%' then 13 when symbol like 'n%' then 14 when symbol like 'o%' then 15 when symbol like 'p%' then 16
when symbol like 'q%' then 17 when symbol like 'r%' then 18 when symbol like 's%' then 19 when symbol like 't%' then 20
when symbol like 'u%' then 21 when symbol like 'v%' then 22 when symbol like 'w%' then 23 when symbol like 'x%' then 24
when symbol like 'y%' then 25 when symbol like 'z%' then 26
end) order by symbol
) as RankInGroup
from @table
)
select a.Symbol as Symbol, b.Symbol as ParentSymbol
from cte a
left join cte b on a.GroupNumber = b.GroupNumber and a.RankInGroup = b.RankInGroup + 1;