3

问题:

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

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

这应该是一个' '

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

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


我试过的:

现在,我想既然时间总是在同一个地方(这对我来说很重要),我可以只取时间中数字的子字符串并对其进行排序;首先是上午,然后是下午

我可以按 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
);

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

正如你所看到的(在小时字段中)01 然后 02 然后又回到 01...?

无论如何,这里有一个类似的问题已经悬赏,如果你回答这个问题或那个问题,你将获得赏金,这对于其他情况也很有用

编辑: 我真正想回答的问题如何按字符串的子字符串排序;抱歉,我可以发誓我已经更改了这个,说我想按任何字符串/日期/任何我想知道如何执行以下操作的单个数字排序:Order By Val(Mid(ColumnName,StartPos,结束位置))

注意: Order By 给出了完全错误的结果。

4

3 回答 3

3

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

下面的快速和肮脏功能可处理单个和两位数月份。它需要 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 下工作,则将 ANSI 通配符与 Alike 一起使用。

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;
于 2012-04-23T18:12:58.847 回答
2

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

如果您真的想将其保留为字符串,请至少确保使用对排序/本地化安全的标准 ISO8601 格式(大约 YYYY-MM-DDTHH:MM.ssss)。

于 2012-04-23T18:11:37.970 回答
1

我没有要测试的表格,但是我想给出我的想法。
我将使用 Left、Mid 和 Right 函数以及 CDate 和 CInt 函数。
我将得到时间字段的最左边部分(16 个字节),为秒和 PM/AM 指示符添加一个“:00”。可以使用 CDate 将此字符串转换为日期。
然后我将获取秒部分并将它们转换为整数。
现在可以在不使用 UNION 的情况下对第一部分 (TTI) 和第二部分 (TTS) 进行排序。
但是有一个问题,有些日期包含只有 1 个字符的月份,(es:4 月 4 日 vs 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;
于 2012-04-23T19:05:13.633 回答