【问题标题】:query for finding the most frequently changing record查询查找最频繁更改的记录
【发布时间】:2020-05-02 05:27:30
【问题描述】:
source   |  voltage | timestamp
CIRCUIT1 | 2.4 | XXX
CIRCUIT1 | 2.4 | XXX
CIRCUIT1 | 2.5 | XXX
CIRCUIT1 | 2.4 | XXX
CIRCUIT1 | 2.4 | XXX
CIRCUIT1 | 2.6 | XXX
CIRCUIT1 | 2.4 | XXX
CIRCUIT1 | 2.4 | XXX
CIRCUIT1 | 2.4 | XXX

CIRCUIT2 | 2.4 | XXX
CIRCUIT2 | 2.5 | XXX
CIRCUIT2 | 2.4 | XXX
CIRCUIT2 | 2.4 | XXX
CIRCUIT2 | 2.5 | XXX
CIRCUIT2 | 2.4 | XXX
CIRCUIT2 | 2.5 | XXX
CIRCUIT2 | 2.4 | XXX
CIRCUIT2 | 2.5 | XXX

CIRCUIT3 | 2.4 | XXX
CIRCUIT3 | 2.4 | XXX
CIRCUIT3 | 2.8 | XXX
CIRCUIT3 | 2.4 | XXX
CIRCUIT3 | 2.4 | XXX
CIRCUIT3 | 2.8 | XXX
CIRCUIT3 | 2.4 | XXX
CIRCUIT3 | 2.4 | XXX
CIRCUIT3 | 2.4 | XXX

输出应该只是 CIRCUIT2

CIRCUIT1 的电压值仅变化 2 次 CIRCUIT2 的电压值变化 4 次 即使变化很大,CIRCUIT3 的电压值也仅变化 2 倍

谁能告诉我如何继续编写将输出 CIRCUIT2 作为答案的 sql 查询?

(我又添加了一列TIMESTAMP)

【问题讨论】:

  • Mysql Sql Server 选择你正在使用的那个!!
  • 还需要有一些其他列才能找到记录的顺序
  • @Pரதீப் 我添加 sql server 只是为了扩大响应范围,但如果违反规则我将删除。
  • 是的,你不应该这样做,因为Sql Server 的答案看起来像这样 rextester.com/YBZPB69250 但这甚至不会在 Mysql 中编译
  • 请不要使用不相关的标签。

标签: mysql sql


【解决方案1】:

这是一种方法(不确定这是Mysql中的最佳方法)

SELECT *
FROM   tabtest
WHERE  source = (SELECT a.source
                 FROM   (SELECT a.source,a.voltage,a.timestamp,Count(*) AS rn
                         FROM   tabtest a
                                JOIN tabtest b
                                  ON a.source = b.source
                                     AND a.timestamp >= b.timestamp
                         GROUP  BY a.source,a.voltage,a.timestamp) a
                        LEFT JOIN (SELECT a.source,a.voltage,a.timestamp,Count(*) AS rn
                                   FROM   tabtest a
                                          JOIN tabtest b
                                            ON a.source = b.source
                                               AND a.timestamp >= b.timestamp
                                   GROUP  BY a.source,a.voltage,a.timestamp) b
                               ON a.source = b.source
                                  AND a.rn = b.rn + 1
                 GROUP  BY a.source
                 ORDER  BY Sum(CASE WHEN a.voltage <> COALESCE(b.voltage, a.voltage) THEN 1 ELSE 0 END) DESC Limit 1) 

这里的想法是为source 中的每条记录查找先前的voltage 值,然后仅当当前记录与先前记录发生变化时才使用条件聚合对记录进行计数。

使用窗口函数http://rextester.com/PJFL7743 更容易

【讨论】:

    【解决方案2】:

    我建议如下:

    • 查找上一个版本
    • 计算不同的次数
    • 按此计数汇总
    • 选择值最少的“n”行

    这看起来像:

    select source, sum(prev_voltage <=> voltage) as changes
    from (select t.*,
                 (select t2.voltage
                  from t t2
                  where t2.source = t.source and t2.timestamp < t.timestamp
                  order by t2.timestamp desc
                  limit 1
                 ) prev_voltage
          from t
         ) t
    group by source
    order by changes;
    

    这将按更改次数对所有源进行排序。在外部查询中添加 limit 以获取前 1 个。

    【讨论】:

      【解决方案3】:

      我最终使用了这里提到的第二种解决方案。

      https://stackoverflow.com/a/6565970/522882 然后使用 group by 和 count() 然后按 count() 排序并将结果限制为 1。

                 SELECT System, Timestamp, StatusA, StatusB, count(*) as ct
      FROM
        ( SELECT (@statusPre <> statusA AND @systemPre=System) AS statusChanged
               , System, Timestamp, StatusA, StatusB
               , @statusPre := StatusA
               , @systemPre := System
          FROM tableX
             , (SELECT @statusPre:=NULL, @systemPre:=NULL) AS d
          ORDER BY System
                 , Timestamp
        ) AS good
      WHERE statusChanged GROUP BY Systen ORDER BY ct DESC limit 1 ;
      

      感谢大家的回复。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多