-1

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

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

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

4

2 回答 2

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表达式旨在排除非整数的数字格式。

于 2013-02-23T21:19:32.877 回答
0

这个问题比看起来更棘手,因为它很容易出错,或者以这样一种方式编写它,它现在适用于您给定的数据集,但无法适用于其他数据集。

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

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

  1. 确定字符串中的 ~ 字符数。
  2. 在波浪号上拆分数据。
  3. 确保其中一个值是日期时间
  4. 确保另一个值是整数。

4 个项目中只有 1 个内置于 SQL Server。有一个名为 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
于 2013-02-23T21:34:45.017 回答