拆分和分析数据

时间:2013-02-23 19:21:57

标签: sql tsql

我有一个有时包含如下字符串的字段:2/23/2013 12:25:55~45

我需要在〜处拆分字符串,并确定〜左边的内容是否是有效的日期时间值,而〜的右边是有效整数。基本上我想要返回的是真/假,无论这些条件是否正确。

请记住,该字段可能包含空值,可能包含任何其他类型的数据,并且可能包含多个波形。在所有情况下,我都需要返回false。我需要返回true的唯一时间是该字段包含日期/时间值,单个代字号和整数。

2 个答案:

答案 0 :(得分:2)

在SQL Server中,您可以执行以下操作:

select (case when col like '%~%'
             then (case when isdate(left(col, charindex('~', col) - 1)) = 1 and
                             isnumeric(substring(col, charindex('~', col)+1, 1000)) = 1 and col not like '%~%.%' and col not like '%~%e%'
                        then 1
                        else 0
                   end)
             else 0
       end) as IsFunkyFormat, substring(col, charindex('~', col)+1, 1000), left(col, charindex('~', col) - 1)

嵌套的情况是在找不到分隔符时防止错误。 not like表达式旨在排除非整数的数字格式。

答案 1 :(得分:0)

这个问题比它看起来更棘手,因为它很容易出错,或者以现在可用的方式编写它,用于给定的数据集,但不能用于其他数据集。 / p>

如果这是您存储在数据库中的数据,我强烈建议您了解数据库规范化。规范化的一个原则是您只在一列中存储一个值。在这种情况下,您将日期时间和整数值存储在同一列中。将数据存储在多个列中会好得多。

话虽如此,我知道有时您会获得一些需要导入数据库的原始数据。很多时候,我们无法控制我们给出的原始数据,因此我们必须使用SQL体操。在这种特殊情况下,有几种不同类型的后翻将是有用的。

  1. 确定字符串中〜字符的数量。
  2. 分割代字号上的数据。
  3. 确保其中一个值是日期时间
  4. 确保其他值是整数。
  5. SQL Server内置了4个项目中的1个。有一个函数名IsDate,它接受一个字符串参数并返回一个位,指示字符串表示的日期是否可以转换为日期。

    要确定字符串中〜的数量,诀窍是确定带波形符的字符串的长度,以及没有波形符的字符串的长度。我们可以通过这样做来确定哪些行包含单个代字号:

    When Len(Data) = Len(Replace(Data, '~', '')) + 1
    

    要解决的另一个棘手问题是确定字符串是否代表整数。有多种方法可以做到这一点,但我最喜欢的方法是将硬编码值连接到您的数据,然后测试数字。例如,IsNumeric函数将为字符串1e4返回true,因为e表示科学记数法,1e4可以解释为1000.所以如果你这样做:

    IsNumeric(Data + 'e0')
    

    对于科学记数法,这将返回false,因为数据类似于1e4,它连接到'e0'以获得不是数字的'1e4e0'。类似地,我们可以将.0连接到字符串以检查小数。如果您的数据是45.2(这是数字)并且您将.0连接到它,则会得到'45 .2.0',这不是数字。您还可以在测试中添加“ - ”以检查正数。 ' - 20'是数字,但' - '+' - 20'(即' - 20')不是数字。

    Select  YourColumnHere, 
            Len(Replace(YourColumnHere, '~', '')) + 1,
            Case When Len(YourColumnHere) = Len(Replace(YourColumnHere, '~', '')) + 1
                 Then 
                        Case When IsDate(Left(YourColumnHere, CharIndex('~', YourColumnHere)-1)) = 1
                             Then 
                                    Case When Right(YourColumnHere, Len(YourColumnHere)-CharIndex('~', YourColumnHere)) > ''
                                         Then IsNumeric('-' + Right(YourColumnHere, Len(YourColumnHere)-CharIndex('~', YourColumnHere)) + '.0e0')
                                         Else 0 
                                         End
                             Else 0
                             End
                 Else 0
                 End
    From    YourTableNameHere