问题:
我的表格中的某些字段的日期格式错误,它们是使用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
);
只是为了看看它是否会按小时订购,但它没有给我这个:
你可以看到它(在小时字段中)01然后02然后它回到01 ...?
无论如何有一个类似的问题here如果你回答这个问题或者那个问题,你会获得赏金,这对于了解其他场景也是有用的
修改 我真正想要的问题回答了如何按字符串的子串进行排序;抱歉我已经发了晚编辑我已经改变了这个,说我想按任意字符串/日期/任何东西的单个数字排序我想知道我怎么能这样做: 按Val排序(中(ColumnName,StartPos,EndPos))
注意:那个Order By会给出完全错误的结果。
答案 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;