对访问数据进行排序(日期时间格式错误)

时间:2012-04-23 17:50:14

标签: c# ms-access

问题:

我的表格中的某些字段的日期格式错误,它们是使用C#中的.ToString()方法格式化的,但是我输了一个字形错误并输入如下: MM / dd / yyyy hh:mm / ss tt

现在,如果仔细观察,你会看到MM / dd / yyyy hh:mm ----> ' / '< --- ss

假设是''

然后我先在我的c#代码中修复它(意味着某些值的格式为: MM / dd / yyyy hh:mm:ss tt

问题是,我正在尝试按日期顺序从表中选择值(我不能只按'Datefieldnamehere'排序),因为某些字段格式错误,带有'/'< / p>


我的尝试:

现在,我想,因为时间总是在同一个地方(这对我来说重要)我可以在时间中取出数字的子串并按顺序排列;首先是 AM ,然后是 PM

我可以通过MID([ColumnName],11,2),MID([ColumnName],14,2),MID([ColumnName],16,2)进行排序,因为无论分隔符如何,每个日期始终位于格式M / dd / yyyy hh / mm / ss tt

所以我试过:


(
SELECT SN, StatusCode, Time, Mid(Time,14,2) + ':'+ Mid(Time,17,2) AS TTI
FROM OrderStatus
WHERE StatusCode = 'Finished' and Left(Time,10) = '4/20/2012'
AND Time LIKE '*AM'
ORDER BY Val(Mid([Time],11,2)) DESC
)
UNION ALL (
SELECT SN, StatusCode, Time, Mid(Time,14,2) + ':'+ Mid(Time,17,2) AS TTI
FROM OrderStatus
WHERE StatusCode = 'Finished' and Left(Time,10) = '4/20/2012'
AND Time LIKE '*PM'
ORDER BY Val(Mid([Time],11,2)) DESC
);

只是为了看看它是否会按小时订购,但它没有给我这个: Err

你可以看到它(在小时字段中)01然后02然后它回到01 ...?

无论如何有一个类似的问题here如果你回答这个问题或者那个问题,你会获得赏金,这对于了解其他场景也是有用的

修改 我真正想要的问题回答了如何按字符串的子串进行排序;抱歉我已经发了晚编辑我已经改变了这个,说我想按任意字符串/日期/任何东西的单个数字排序我想知道我怎么能这样做:  按Val排序(中(ColumnName,StartPos,EndPos))

注意:那个Order By会给出完全错误的结果。

3 个答案:

答案 0 :(得分:3)

我的直觉是创建一个函数并在Access UPDATE语句中运行一次,以转换存储的值以匹配所需的格式。

快速&amp;下面的脏功能应对单个月和两个月的数字。它需要Access 2000或更高版本。

? FixTimeData("4/20/2012 01:34/09 PM")
4/20/2012 01:34:09 PM
? FixTimeData("12/20/2012 01:34/09 PM")
12/20/2012 01:34:09 PM

Public Function FixTimeData(ByVal pIn As String) As String
    Dim astrPieces() As String
    Dim strOut As String
    astrPieces = Split(pIn, " ")
    strOut = astrPieces(0) & " " & _
        Replace(astrPieces(1), "/", ":") & " " & _
        astrPieces(2)
    FixTimeData = strOut
End Function

然后是一个类似于此的UPDATE语句......

UPDATE OrderStatus
SET time_field = FixTimeData(time_field)
WHERE time_field Like "*/*/*/*";

如果在ADO而不是DAO下运行语句,请在WHERE子句中更改为ANSI通配符。

WHERE time_field Like "%/%/%/%";

如果您希望相同的语句在ADO或DAO下工作,请使用带有ALike的ANSI通配符。

WHERE time_field ALike "%/%/%/%";

我使用time_field作为您使用Time的字段名称,因为Time是保留字。如果您无法更改字段名称,请在查询中用方括号括起来。

修改:我的目的是修复数据,以便您可以根据Right(time_field, 11)

进行可靠的排序

Edit2 :要根据“较高”分钟数字进行排序,请查看您是否可以采用此方法,假设您已修复存储的日期/时间字符串:

? Left(Format(Minute("4/23/2012 04:02:40 PM"), "00"), 1)
0
? Left(Format(Minute("4/23/2012 04:12:40 PM"), "00"), 1)
1
? Left(Format(Minute("4/23/2012 04:22:40 PM"), "00"), 1)
2

虽然Minute()函数接受一个字符串,但我可能会使用CDate()将字符串显式转换为日期/时间,然后再将其提供给Minute()

所以...如果我没有完全误入歧途......在这样的查询中尝试这种方法:

SELECT
    Left(Format(Minute(CDate(time_field)), "00"), 1) AS upper_minute,
    OrderStatus. *
FROM OrderStatus
ORDER BY 1;

答案 1 :(得分:2)

将日期归档为实际日期字段而不是字符串。使用2个更新将所有值迁移到新字段 - 一个选择旧格式的所有行,另一个选择new。删除日期的字符串列,享受正确输入的数据。

如果你真的想把它保留为字符串,至少要确保使用标准的ISO8601格式(约为YYYY-MM-DDTHH:MM.ssss),这对于排序/本地化是安全的。

答案 2 :(得分:1)

我没有可以测试的表格,但我想提出我的想法 我将使用左,中,右功能以及CDate和CInt功能 我将获得时间字段的最左边部分(16个字节),为秒和PM / AM指示符添加“:00”。可以使用CDate将此字符串转换为日期 然后我将得到秒部分并将它们转换为整数 现在订单可以在不使用UNION的情况下订购第一部分(TTI),然后订购第二部分(TTS)。 但是有一个问题,有些日期包含一个只有1个字符的月份(es:4月4日对12月12日)幸运的是,我们可以使用IIF运算符为中,右和左选择正确的数字。

编辑:

SELECT 
SN, StatusCode, Time, 
IIF(Len(Time) = 22, Left(Time,16) + ':00' + Right(Time,2), Left(Time,15) + ':00' + Right(Time,2)) AS TTI, 
IIF(Len(Time) = 22, Mid(Time, 18,2), Mid(Time, 17,2)) as TTS
FROM OrderStatus 
WHERE StatusCode = 'Finished' and Left(Time,10) = '4/20/2012' 
ORDER BY CDate(IIf(Len([Time])=22,Left([Time],16)+ ':00 ' + Right([Time],2),Left([Time],15)+ ':00 ' + Right([Time],2))) DESC , 
         CInt(IIf(Len([Time])=22,CInt(Mid([Time],18,2)),CInt(Mid([Time],17,2)))) DESC;