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

标签 mysql sql mysql-workbench

我一直在看其他几个问题,但我无法从中找出解决办法。首先是描述,然后是我从其他线程中丢失的内容。(负责人:我非常清楚我们数据库的非标准化结构,这是我以前在会议上讨论过的问题,但这是我们拥有的,也是我必须处理的问题。)
背景说明
我们有一台在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 ORDER BY 与复合 PK

PHP 通过 'Key' => 'Value' 列回显所有表行 - 经验

php - 我用日期选择器选择的日期输入没有插入到我的数据库中

php - 如何使用函数从 mysql 中提取多行

mysql - 如果MySQL中没有配对,如何从连接表中进行选择

MySQL 使用串联查询多个表

mysql - 这个查询有什么问题?我正在尝试创建一个带有一些主 id 的练习小表来进行匹配,但我在这里没有找到错误

mysql - 将包含空值的列从 Excel 导入到 MYSQL Workbench 时出现问题

MySQL - 使用表数据两次

mysql - GROUP BY 在 SELECT 中选择