问题描述
日期字段 | stringField1 | stringField2 | booleanField |
---|---|---|---|
11/09/20 17:15 | 约翰 | 尼克 | 0 |
12/09/20 17:00 | 约翰 | 玛丽 | -1 |
13/09/20 17:30 | 安 | 约翰 | 0 |
13/09/20 19:30 | 凯特 | 艾伦 | 0 |
19/09/20 19:30 | 安 | 小姐 | 0 |
20/09/20 17:15 | 吉姆 | 乔治 | 0 |
20/09/20 19:30 | 约翰 | 尼克 | 0 |
27/09/20 15:00 | 约翰 | 玛丽 | -1 |
27/09/20 17:00 | 安 | 约翰 | -1 |
27/09/20 19:30 | 凯特 | 艾伦 | 0 |
28/09/20 18:30 | 安 | 小姐 | -1 |
03/10/20 18:30 | 吉姆 | 乔治 | -1 |
04/10/20 15:00 | 约翰 | 尼克 | 0 |
04/10/20 17:15 | 约翰 | 玛丽 | 0 |
04/10/20 20:45 | 安 | 约翰 | 0 |
05/10/20 18:30 | 凯特 | 艾伦 | 0 |
17/10/20 15:00 | 吉姆 | 乔治 | 0 |
17/10/20 17:15 | 约翰 | 尼克 | 0 |
18/10/20 15:00 | 约翰 | 玛丽 | -1 |
18/10/20 17:15 | 安 | 约翰 | 0 |
注意事项:
Public Function STR2TIME(sTime As String) As Date
Dim arr() As String
sTime = Replace(sTime,".","/")
arr = Split(sTime," ")
STR2TIME = DateValue(Format(arr(0),"dd/mm/yyyy")) + TimeValue(arr(1))
End Function
- qr1 按 STR2TIME(dateField) ASC 排序
日期字段 | stringField1 | stringField2 | booleanField | countField |
---|---|---|---|---|
11/09/20 17:15 | 约翰 | 尼克 | 0 | 1 |
12/09/20 17:00 | 约翰 | 玛丽 | -1 | 2 |
13/09/20 17:30 | 安 | 约翰 | 0 | 1 |
13/09/20 19:30 | 凯特 | 艾伦 | 0 | 2 |
19/09/20 19:30 | 安 | 小姐 | 0 | 3 |
20/09/20 17:15 | 吉姆 | 乔治 | 0 | 4 |
20/09/20 19:30 | 约翰 | 尼克 | 0 | 5 |
27/09/20 15:00 | 约翰 | 玛丽 | -1 | 6 |
27/09/20 17:00 | 安 | 约翰 | -1 | 1 |
27/09/20 19:30 | 凯特 | 艾伦 | 0 | 1 |
28/09/20 18:30 | 安 | 小姐 | -1 | 2 |
03/10/20 18:30 | 吉姆 | 乔治 | -1 | 1 |
04/10/20 15:00 | 约翰 | 尼克 | 0 | 1 |
04/10/20 17:15 | 约翰 | 玛丽 | 0 | 2 |
04/10/20 20:45 | 安 | 约翰 | 0 | 3 |
05/10/20 18:30 | 凯特 | 艾伦 | 0 | 4 |
17/10/20 15:00 | 吉姆 | 乔治 | 0 | 5 |
17/10/20 17:15 | 约翰 | 尼克 | 0 | 6 |
18/10/20 15:00 | 约翰 | 玛丽 | -1 | 7 |
18/10/20 17:15 | 安 | 约翰 | 0 | 1 |
问题
我尝试了很多东西,但都给出了错误的数字结果。
最后,我认为 从当前日期到前一个日期计算零(最大和小于当前日期),可以解决问题:
SELECT t.*,(SELECT COUNT(*)
FROM qr1 tt
WHERE booleanField = 0
AND STR2TIME(tt.dateField) >= (SELECT TOP 1 dateField
FROM qr1
WHERE booleanField = -1
AND STR2TIME(dateField) < STR2TIME(t.dateField)
ORDER BY STR2TIME(dateField) DESC
)
AND STR2TIME(tt.dateField) <= STR2TIME(t.dateField)
) AS CountMatches
FROM qr1 t;
但在 countField 上仍然给我错误的数字结果:
countField |
---|
0 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
1 |
2 |
3 |
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
13 |
我做错了什么?我无法得到它。如何得到想要的结果?
编辑:
我将根据 @Gordon Linoff 和 @Gustav 的答案发布最终代码,稍微简化。
变更说明:
- 我在这一步去掉了转换函数。我没有转换 7 次 * 每条记录,而是在第一个查询中只转换一次,这里的值已准备好进行比较。
- 我省略了检查零,因为它没有必要。
- 我添加了 NZ 函数以在内部子查询返回 NULL 时获取值。那就是没有任何日期较小的 yes 可以计算(通常是第一条记录)。
- 剩下的唯一问题是,使用 NZ 时,我得到的值比我需要的值少 1,因此我在 dateField 中添加了 -1 以再计数 1。
代码如下:
SELECT t.*,(SELECT COUNT(*) FROM qr2 tt
WHERE tt.dateField <= t.dateField
AND tt.dateField > NZ((SELECT TOP 1 dateField FROM qr2
WHERE booleanField = True
AND dateField < t.dateField
ORDER BY dateField DESC
),tt.dateField - 1)
) AS CountMatches
FROM qr2 AS t;
解决方法
一个明显的问题是:
AND STR2TIME(tt.dateField) >= (SELECT TOP 1 dateField
这应该是:
AND STR2TIME(tt.dateField) >= (SELECT TOP 1 STR2TIME(dateFielda)
其次,你有:
WHERE booleanField = 0
但我认为这个过滤器不合适。
,这是可行的,虽然有点复杂:
Select
qr1.dateField,qr1.stringField1,qr1.stringField2,qr1.booleanField,(Select Count(*) From qr1 As t1
Where
(t1.booleanfield = true And t1.dateField = qr1.dateField)
Or
(t1.booleanfield = false And t1.dateField <= qr1.dateField And
t1.dateField >= Nz(
(Select Top 1 dateField From qr1 As t
Where t.dateField < qr1.dateField And t.booleanField = True
Order By t.dateField Desc),t1.dateField ))) As countField
From
qr1;
输出:
你的字符串转换器可以用这个表达式替换:
TrueDate = CDate(Replace(TextDotDate,".","/"))
你应该在更早的状态应用这个,比如在 qr1
中。