我有一个应用程序可以在不同的时间轮询不同的垃圾箱,并根据重量计算每个垃圾箱中的小部件数量。轮询每隔几分钟完成一次,结果带有时间戳并添加到MySQL表中。该表包含以下3列。该示例显示了3个箱(A,B和C),但同一个小部件可能有1到10个箱。 (微小的小部件可能只在1或2个箱子中,较大的小部件可能占用更多的箱子)
timestamp bin Widget_Count
--------------------------
1 A 8
2 B 7
3 C 4
4 A 1
5 B 3
6 C 5
7 A 6
8 B 7
9 C 2
应用程序需要生成“库存历史”报告 - 这将涉及在每个时间步计算什么是总数。在那个时间步的所有箱子里的物品。对于此示例,报告将仅包含下面的timestamp列和CountHistory列(最后一列)(显示其他列只是为了显示计算)
在时间1,A已经被轮询并且有8个小部件。 B和C尚未被调查。所以总数是8。
在时间2,B已经被轮询并且有7个小部件。所以总数是17
在时间3,C已经被轮询并且有4个小部件。所以总数是19
在时间4,A再次轮询,只有一个小部件。所以总数现在是1 + 4 + 7 = 12
..等等。
timestamp bin Widget_ A B C CountHistory
Count (stock flow)
--------------------------------------------------------
1 A 8 8 0 0 8
2 B 7 8 7 0 15
3 C 4 8 7 4 19
4 A 1 1 7 4 12
5 B 3 1 3 4 8
6 C 5 1 3 5 9
7 A 6 6 3 5 14
8 B 7 6 7 5 18
9 C 2 6 7 2 15
对于如何最好地解决这个问题,我将不胜感激。我试图创建一个临时表,使用游标滚动每个记录但无法获得正确的查询。
(之前我曾问过一个相关的问题,但我没有正确地提出这个问题,并且也提到了这个例子。Need Help with queries (views) in Microsoft Access)
答案 0 :(得分:2)
我认为这将满足您的需求。内部查询查找每个时间戳更改每个bin的最新时间戳。
SELECT m.timestamp, SUM(w.Widget_Count) AS CountHistory
FROM (
SELECT a.timestamp, b.bin, MAX(b.timestamp) AS intMostRecentTimestamp
FROM WidgetTable a
CROSS JOIN WidgetTable b
WHERE a.timestamp >= b.timestamp
GROUP BY a.timestamp, b.bin, a.Widget_Count
) m
INNER JOIN WidgetTable w ON m.intMostRecentTimestamp = w.timestamp
GROUP BY m.timestamp
ORDER BY m.timestamp
答案 1 :(得分:1)
没有实际模型(DDL)和数据(包括预期输出),我不确定我是否会尝试提供实际的,语法检查的示例SQL。虽然我认为这在应用程序代码或游标中很容易实现,但我认为它可以在一个查询中完成。
那就是说,就像这样 - 考虑这个100%伪代码:
SELECT
timestamp,
bin,
widget_count,
(SELECT A that is most recent and <= current row's timestamp) A,
(SELECT B that is most recent and <= current row's timestamp) B,
(SELECT C that is most recent and <= current row's timestamp) C,
(SELECT sum of last three columns) CountHistory
FROM
widget_bin_table
可能可以使用连接而不是子查询来完成,并且连接可能会更有效。但是你明白了。
编辑:好的,这个问题让大脑血液流动,我无法休息,直到我解决它让我满意。然后我回来发布更新,保罗已经回答了一个更加优雅的解决方案。 :)
以下是我使用SQL(使用SQL Server)的解决方案,以防有人关心:
SELECT
timestamp, bin, widget_count, A, B, C, A + B + C CountHistory
FROM
(
SELECT
wb.timestamp,
wb.bin,
wb.widget_count,
ISNULL((SELECT TOP 1 widget_count FROM widget_bin wb1 WHERE wb1.bin = 'A'
AND wb1.timestamp <= wb.timestamp ORDER BY wb1.timestamp DESC), 0) A,
ISNULL((SELECT TOP 1 widget_count FROM widget_bin wb1 WHERE wb1.bin = 'B'
AND wb1.timestamp <= wb.timestamp ORDER BY wb1.timestamp DESC), 0) B,
ISNULL((SELECT TOP 1 widget_count FROM widget_bin wb1 WHERE wb1.bin = 'C'
AND wb1.timestamp <= wb.timestamp ORDER BY wb1.timestamp DESC), 0) C
FROM
widget_bin wb
) sub