草庐IT

mysql - MySQL - 仅计算特定日期之间的唯一实例

coder 2023-10-23 原文

我一直在看其他几个问题,但我无法从中找出解决办法。首先是描述,然后是我从其他线程中丢失的内容。(负责人:我非常清楚我们数据库的非标准化结构,这是我以前在会议上讨论过的问题,但这是我们拥有的,也是我必须处理的问题。)
背景说明
我们有一台在25个位置生产产品的机器。这些产品的生产数据被记录在一个表格中,其中包括记录每个位置的电流和电压。只有当机器实际生产产品(即机器中有产品)时才会记录此信息。产品不存在时,不记录任何内容。
这台机器可以在两种不同的生产模式下运行:全生产和研发生产。全面生产意味着产品不断插入,以便每个实例始终都有一个产品(即机器中始终有25个产品)。第二种模式,研发生产,一次只生产一个产品(即一个产品进入机器,逐个经过25个实例,当这一个完成后,第二个产品进入机器)。
澄清:每当产品出现时,每个位置每秒记录一次数据,这意味着在整个生产运行时每秒记录25个实例。当R&D模式运行时,位置1将连续20秒有~20个实例,位置2将连续20秒有~20个实例,依此类推。
表结构
生产数据:
ID(自动增量)
产品ID
位置
时间(记录数据的时间戳)
电流(安培)
电压(伏特)
问题
我们想计算机器的正常运行时间,但我们想将生产模式和研发模式的正常运行时间分开,我们想每周分离这些数据。
猜测解
由于我们每秒钟都会记录实例,所以我可以计算表中时间值的不同实例的数量,以了解生产和研发模式的总正常运行时间。为了找到研发模式,我可以放心地说,只要有一个时间实例只有一个条目,我就在研发模式下运行(生产模式将有25个实例)。
迄今为止的进展
我有以下查询,总结所有不同的实例,以找到生产和研发模式:

SELECT YEARWEEK(time) AS YWeek, COUNT(DISTINCT time) AS Time_Seconds, ROUND(COUNT(DISTINCT time)/3600, 1) AS Time_Hours 
FROM Database.productiondata
WHERE YEARWEEK(time) >= YEARWEEK(curdate()) - 21
GROUP BY YWeek;

此查询找出表中有多少个不同的时间实例,并按周统计这些实例的数量和组。
问题
上面的查询统计表中存在的实例数量,但我只想找到唯一的实例。基本上,我试图找到一些类似于if count(time)=1的东西,然后计算那个实例,如果count(time)>1,那么根本不计算它(distinct仍然计算这个)。
我查看了其他几个so线程,但几乎所有线程都解释了如何找到具有distinct的唯一值,这只完成了我所要查找的值的一半。我得到的最接近的是使用having子句的this。我目前陷入了以下困境:
SELECT YEARWEEK(time) as YWeek, COUNT(Distinct time) As Time_Seconds, ROUND(COUNT(Distinct time)/3600, 1) As Time_Hours
FROM 
(SELECT * FROM Database.productiondata
WHERE time > '2014-01-01 00:00:00'
GROUP BY time
HAVING count(time) = 1) as temptime
GROUP BY YWeek
ORDER BY YWeek;

这里的问题是,我们在嵌套的select子句中有一个group by time,它将永远占用(今年只有大约500万行,所以我可以理解)。我的意思是,从语法上来说,我认为这是正确的,但要执行它需要永远。甚至在这段时间里都要解释清楚。
我就在那里。这是正确的方法还是有其他更聪明/需要更少的查询时间/避免GROUPBY时间子句的方法?
编辑:作为一个例子,我们有这个表(很抱歉设置了格式,不知道如何在这里设置表格式)
id    position    time
1     1           1
2     2           1
3     5           1
4     19          1
...   ...         ...
25    7           1
26    3           2
27    6           2
...   ...         ...

此表显示了生产运行时的外观。如您所见,在将数据记录到表中时,没有哪个位置获得第一个条目的通用结构;发生的情况是,25个位置在每秒钟内被记录,然后根据可编程逻辑控制器为每个位置发送数据的速度将数据添加到表中。下表显示了该表在研究模式下运行时的外观。
id    position    time
245   1           1
246   1           2
247   1           3
...   ...         ...
269   1           25
270   2           26
271   2           27
...   ...         ...

因为所有的数据都被合并到一个表中,所以我们想知道count(time)正好等于1时有多少个实例,或者我们可以在count(time)严格大于1时查找每个实例。
编辑2:作为对艾伦的答复,这个建议给了我
YWeek    Time_Seconds    Time_Hours
201352   1               0.0
201352   1               0.0
201352   1               0.0
...      ...             ...
201352   1               0.0  (1000 row limit)

而我想要的是
Yweek    Time_Seconds    Time_Hours
201352   2146            35.8
201401   5789            96.5
...      ...             ...
201419   8924            148.7

edit3:我已经收集了目前为止here的尝试和结果,并在查询上方用灰色描述。

最佳答案

通过取消子选择,您可能会获得更好的结果:

SELECT YEARWEEK(time) as YWeek, 
       COUNT(time) As Time_Seconds, 
       ROUND(COUNT(time)/3600, 1) As Time_Hours
FROM Database.productiondata
WHERE time > '2014-01-01 00:00:00'
GROUP BY YWeek
HAVING count(time) = 1)
ORDER BY YWeek;

我假设time上有一个index,但如果没有,您可以通过添加一个来期望性能的显著改善。
更新:
根据最近添加的示例数据,我不确定您的方法是否正确。time列似乎是一个表示秒的INT列,而您使用DATETIME将其视为一个YEARWEEK列。下面我有一个SQL中的工作示例,它完全按照您的要求执行,如果time实际上是一个DATETIME列:
DECLARE @table TABLE
    (
      id INT ,
      [position] INT ,
      [time] DATETIME
    )


INSERT  INTO @table
VALUES  ( 1, 1, DATEADD(week, -1, GETDATE()) )
INSERT  INTO @table
VALUES  ( 1, 1, DATEADD(week, -2, GETDATE()) )
INSERT  INTO @table
VALUES  ( 1, 1, DATEADD(week, -2, GETDATE()) )
INSERT  INTO @table
VALUES  ( 1, 1, DATEADD(week, -2, GETDATE()) )
INSERT  INTO @table
VALUES  ( 1, 1, DATEADD(week, -2, GETDATE()) )
INSERT  INTO @table
VALUES  ( 1, 1, DATEADD(week, -3, GETDATE()) )
INSERT  INTO @table
VALUES  ( 1, 1, DATEADD(week, -3, GETDATE()) )

SELECT  CAST(DATEPART(year, [time]) AS VARCHAR)
        + CAST(DATEPART(week, [time]) AS VARCHAR) AS YWeek ,
        COUNT([time]) AS Time_Seconds ,
        ROUND(COUNT([time]) / 3600, 1) AS Time_Hours
FROM    @table
WHERE [time] > '2014-01-01 00:00:00'
GROUP BY DATEPART(year, [time]) ,
        DATEPART(week, [time])
HAVING COUNT([time]) > 0
ORDER BY YWeek;

关于mysql - MySQL - 仅计算特定日期之间的唯一实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23609148/

有关mysql - MySQL - 仅计算特定日期之间的唯一实例的更多相关文章

  1. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  2. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  3. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  4. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  5. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  6. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  7. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  8. ruby - 检查日期是否在过去 7 天内 - 2

    我的日期格式如下:"%d-%m-%Y"(例如,今天的日期为07-09-2015),我想看看是不是在过去的七天内。谁能推荐一种方法? 最佳答案 你可以这样做:require"date"Date.today-7 关于ruby-检查日期是否在过去7天内,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/32438063/

  9. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  10. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

随机推荐