2009-09-13 37 views
1

我需要过滤掉SQL(SQL Server 2008)表中的垃圾数据。我需要识别这些记录,并将其提取出来。SQL查询-LEFT 1 = char,RIGHT 3-5 =名称中的数字

  • 字符[0] = A ... Z,a到z
  • 字符[1] = 0..9
  • 字符[2] = 0..9
  • 字符[3 ] = 0..9
  • 字符[4] = 0..9

{不允许空白}

基本上,一个干净的重线看起来就像这样:

  • T1234,U2468,K123,P50054(4个记录的例子)

垃圾数据是这样的:

  • T12 ..,.T12,MARK ,TP1,SP2,BFGL,BFPL(7个记录的例子)

有人可以帮助一个SQL查询做一个左和右方法并提取这些字符,并做一个像我N还是什么?

虽然功能会很棒!

+0

Riann:增加了一个SQL Server 2008的功能,你可以使用,如果你需要它。 –

回答

4

下应在几个不同系统的工作:

SELECT * 
FROM TheTable 
WHERE Data LIKE '[A-Za-z][0-9][0-9][0-9][0-9]%' 
AND Data NOT LIKE '% %' 

这种做法确实将匹配P2343,P23423JUNK,以及其他类似的文本,但要求的格式是A0000 *。现在

,如果OP意味着第一个位置的格式是一个字符,所有随后的位置是数字,如A0 +,然后使用以下(在SQL Server和大量其他数据库系统):

SELECT * 
FROM TheTable 
WHERE SUBSTRING(Data, 1, 1) LIKE '[A-Za-z]' 
AND SUBSTRING(Data, 2, LEN(Data) - 1) NOT LIKE '%[^0-9]%' 
AND LEN(Data) >= 5 

将这一到SQL Server 2008的功能,因为这似乎是你最喜欢的东西,你可以写:

CREATE FUNCTION ufn_IsProperFormat(@data VARCHAR(50)) 
RETURNS BIT 
AS 
BEGIN 
    RETURN 
    CASE 
     WHEN SUBSTRING(@Data, 1, 1) LIKE '[A-Za-z]' 
     AND SUBSTRING(@Data, 2, LEN(@Data) - 1) NOT LIKE '%[^0-9]%' 
     AND LEN(@Data) >= 5 THEN 1 
     ELSE 0 
     END 
END 

...并调用到它像这样:

SELECT * 
FROM TheTable 
WHERE dbo.ufn_IsProperFormat(Data) = 1 

...此查询需要改变为Oracle查询,因​​为甲骨文似乎并不支持在LIKE子句括号标记:

SELECT * 
FROM TheTable 
WHERE REGEXP_LIKE(Data, '^[A-za-z]\d{4,}$') 

这是扩大GBN在他的回答做,但这些版本允许在不变化的字符串长度OR条件。

编辑:已更新为支持SQL Server和Oracle中用于确保格式A0 +的示例,以便A1324,A2342388和P2342匹配,但A2342JUNK和A234不匹配。

Oracle REGEXP_LIKE代码是从Mark的帖子中借用的,但已更新为支持4位或更多的数字。

添加了实现这些技术的自定义SQL Server 2008方法。

+0

它接受“D1234junk” – gbn

+0

@gbn:你说得对,但如果这是允许的话,我不能说是OP。我知道这个字符串可以超过五个字符,但不清楚从这个帖子可以判断的值的范围。另外,我编辑了这篇文章以处理有关空白空间的规则。它不干净,但它符合标准。 –

2

取决于您的数据库。许多都有正则表达式的功能(注意例子没有经过测试如此检查)

例如甲骨文

SELECT x 
FROM table 
WHERE REGEXP_LIKE(x, '^[A-za-z][:digit:]{4}$') 

Sybase用来LIKE

+0

我相信REGEXP_LIKE是一个Oracle约定,所以它确实取决于正在使用哪个系统。 –

+0

@Mark:借用了我自己的答案。这很好,它可以在Oracle中使用。我将其扩展到{4,}以表示四个或更多匹配,以便像P1234和P123423432这样的字符串也匹配得相同。 –

2

假设你允许3至6位数字在你的例子数则可能更好地使用ISNUMERIC()函数的第2个字符开始:

SELECT * 
FROM TheTable 
-- start with a letter 
WHERE Data LIKE '[A-Za-z]%' 
    -- everything from 2nd character onwards is a number 
    AND ISNUMERIC(SUBSTRING(Data, 2, 50)) = 1 
    -- number doesn't have a decimal place 
    AND Data NOT LIKE '%.%' 

欲了解更多信息,看看MSDN上的ISNUMERIC函数。

还要注意的是:

  • 我受够了数量有限的第二部分以最多50个字符,将其更改为满足您的需求。
  • 严格地说,你应该检查是否有货币符号等,为ISNUMERIC允许它们,以及+/-和其他一些

一个更好的选择可能是创建检查功能第一后的每个字符介于0和9之间(如果使用ASCII码,则为1和0)。

+0

这可以与从ISNUMERIC(SUBSTRING(Data,2,50))到ISNUMERIC(SUBSTRING(Data,2,LEN(Data)-1))的变化一起使用。您还需要验证字符串的长度,该字符串似乎至少需要五个字符。 –

2

您不能在SQL Server中使用正则表达式,因此您必须使用OR。纠正大卫Andres的答案...

WHERE 
    (
    Data LIKE '[A-Za-z][0-9][0-9][0-9]' 
    OR 
    Data LIKE '[A-Za-z][0-9][0-9][0-9][0-9]' 
    OR 
    Data LIKE '[A-Za-z][0-9][0-9][0-9][0-9][0-9]' 
    ) 

大卫的回答允许 “D1234junk” 通过

你也只需要 “[AZ]” 如果你没有大小写

+0

gbn:参见OP,其中“P50054”被认为是有效的,但也超过五个字符。你的方法是有效的,但需要无限扩展。 –

+0

@David:你确实需要一个正则表达式来允许右侧未定义的数字字符。然而,标题说右边有3-5个数字,所以这种方法会做预期的(忽略NULL) – gbn

+0

@gbn:看看我的答案更新。在类似运算符(显然Oracle不支持)支持括号符号的系统中,可以使用NOT LIKE'%[^ 0-9]%'来确保只有数字有效。 –