提取不以特定单词结尾的值

时间:2016-04-28 06:23:50

标签: sql sql-server

我有一张包含一些数据的表格。它可以看起来像这样:

7   Gelb    
8   Schwarz
9   Weiß my color
10  Grau
16  Gelb I  
17  Gelb II 
18  Gelb III    
19  Gelb IV 
27  Schwarz I   
28  Schwarz II  
29  Schwarz III 
30  Schwarz IV  
31  Schwarz V   
32  Schwarz VI  
39  Weiß my color III   
40  Weiß my color IV    
41  Weiß my color V 
42  Weiß my color VI    

如您所见,在某些记录中,我们在惯例<name><space><roman number>

中有罗马数字

例如,有“Gelb”“Weiß我的颜色”“Schwarz”并且还有他们的记录罗马大会。对于某些人来说,例如“Grau”,没有重复项。

所以会有没有罗马数字的唯一颜色名称的记录,例如记录“Grau”,在表格中它可能包含或不包含一些带有它的记录和罗马数字。

罗马数字总是在最后:<name><space><romannumber>

我的目标只是获得独特的名字。因此,我只想提取示例:

7   Gelb    
8   Schwarz    
9   Weiß my color   
10  Grau  

我如何实现这一目标?

我从这开始,就够了吗?

Select Id, Name From MyTable Where Name Not Like = '%<space><anyromancharacter>'

我无法更改数据库的结构。

6 个答案:

答案 0 :(得分:4)

<强>更新

select * from dbo.test
Where value not Like '%[MDILXV]_' Collate SQL_Latin1_General_CP1_CS_AS

第1步:

select * from dbo.test

    id  value
    1   Gelb
    2   Gelb I
    3   Weiß my color III
    4   Weiß my color

当我给出

   select * from dbo.test
    Where value not Like '%[IXLV]' Collate SQL_Latin1_General_CP1_CS_AS

id  value
1   Gelb
4   Weiß my color

答案 1 :(得分:3)

这是我的解决方案:

首先,生成一个罗马数字列表,直到达到指定的限制。然后,从表中提取最后一个单词,并检查它是否存在于罗马数字列表中:

ONLINE DEMO

<p><!-- pagebreak --></p> 

参考:

答案 2 :(得分:1)

我会这样做。首先从here

创建ToRomanNumerals函数

现在创建带有罗马数字的数字表(我已经从1..100创建了它),然后使用LEFT(CHARINDEX)从名称中删除罗马数字,如下所示:

DROP TABLE #Table1

CREATE TABLE #Table1
    ([ID] int, [name] varchar(17))
;

INSERT INTO #Table1
    ([ID], [name])
VALUES
    (7, 'Gelb'),
    (8, 'Schwarz'),
    (9, 'Weiß my color'),
    (10, 'Grau'),
    (16, 'Gelb I'),
    (17, 'Gelb II'),
    (18, 'Gelb III'),
    (19, 'Gelb IV'),
    (27, 'Schwarz I'),
    (28, 'Schwarz II'),
    (29, 'Schwarz III'),
    (30, 'Schwarz IV'),
    (31, 'Schwarz V'),
    (32, 'Schwarz VI'),
    (39, 'Weiß my color III'),
    (40, 'Weiß my color IV'),
    (41, 'Weiß my color V'),
    (42, 'Weiß my color VI')
;

--select name, patindex('%M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})', name) from #Table1
--select name, patindex('% [IVXLC]%', name) from #Table1

;with n as 
(select 1 as n
union all
select n.n+1 as n
from n where n < 100),
nr as
(select n, dbo.ToRomanNumerals(n) r
from n)
select name, nr.r, COALESCE(LEFT(name, PATINDEX('% ' + nr.r, name)), name) from #Table1 t
LEFT JOIN nr ON t.name LIKE '% ' + nr.r

结果:

name              r        
----------------- -------- -----------------
Gelb              NULL     Gelb
Schwarz           NULL     Schwarz
Weiß my color     NULL     Weiß my color
Grau              NULL     Grau
Gelb I            I        Gelb 
Gelb II           II       Gelb 
Gelb III          III      Gelb 
Gelb IV           IV       Gelb 
Schwarz I         I        Schwarz 
Schwarz II        II       Schwarz 
Schwarz III       III      Schwarz 
Schwarz IV        IV       Schwarz 
Schwarz V         V        Schwarz 
Schwarz VI        VI       Schwarz 
Weiß my color III III      Weiß my color 
Weiß my color IV  IV       Weiß my color 
Weiß my color V   V        Weiß my color 
Weiß my color VI  VI       Weiß my color 

(18 row(s) affected)

答案 3 :(得分:0)

我希望这能解决你的问题。 如果没有罗马数字保存空字符串,请在表格中再添加一列,其中只包含罗马数字名称。

select distinct left(NAME,LEN(NAME)-CHARINDEX(RomanNumberColumn,REVERSE(NAME))) FROM TABLE

答案 4 :(得分:0)

这应该是有效的:

select distinct ID, name from YourTable
where right (name,charindex(' ',REVERSE(name))) not like '%[IVXLCDM]%' COLLATE SQL_Latin1_General_CP1_CS_AS

Where只检查NAME列中的最后一个字词,如果它包含X V I L个字符。

答案 5 :(得分:0)

cte替换为您的表名,与列相同。我将id用于数字代码,将name用于名称。

SELECT DISTINCT c.id,
                t.name 
FROM (
    SELECT  c1.name,
            DENSE_RANK() OVER (PARTITION BY c2.name ORDER BY c1.name) as DR
    FROM cte c1
    LEFT JOIN cte c2 
        ON c2.name LIKE c1.name + '%' 
) as t
INNER JOIN cte c
    ON c.name = t.name 
WHERE t.DR = 1

输出:

id          name
----------- -----------------
7           Gelb
8           Schwarz
9           Wei? my color
10          Grau

(4 row(s) affected)
相关问题