从已过滤的查询中删除mysql行

时间:2016-02-21 09:02:48

标签: mysql

我需要来自包含100,000行的mysql数据库表的3个不同查询。用例将是"显示所有内容","显示所有内容,删除重复的值'和"显示那些仅从查询的第一个值中更改了值的内容,在时间范围内"

"显示所有内容"

mysql> select param_id,time,value  
       from PARAMETERS 
       where param_id like 'point_%' and 
       time >= '2015-352T01:56:52.270' 
       and time <= '2015-360T07:20:32.010' 
       order by param_id,time; 
+----------+-----------------------+------------+
| param_id | time                  | value      |
+----------+-----------------------+------------+
| point_x  | 2015-352T01:56:52.270 | 0.0        |
| point_x  | 2015-360T07:20:32.010 | 1.57       |
| point_x  | 2015-360T07:20:32.010 | 1.57       |
| point_y  | 2015-352T01:56:52.270 | -0.5       |
| point_y  | 2015-352T01:56:55.857 | -0.5       |
| point_y  | 2015-360T07:20:32.010 | -0.5       |
| point_y  | 2015-360T07:20:32.010 | -0.5       |
| point_z  | 2015-352T01:56:52.270 | -9.703     |
| point_z  | 2015-360T07:20:32.010 | 0.0        |
| point_z  | 2015-360T07:20:32.010 | 0.0        |
+----------+-----------------------+------------+

&#34;显示所有内容,删除每个param_id&#34;

的重复&#39;值
mysql> select param_id,time,value,count(*) as replicates  
       from PARAMETERS where 
       param_id like 'point_%' and 
       time >= '2015-352T01:56:52.270' and 
       time <= '2015-360T07:20:32.010' 
       group by value,param_id order by param_id,time;
+----------+-----------------------+--------+------------+
| param_id | time                  | value  | replicates |
+----------+-----------------------+--------+------------+
| point_x  | 2015-352T01:56:52.270 | 0.0    |          1 |
| point_x  | 2015-360T07:20:32.010 | 1.57   |          2 |
| point_y  | 2015-352T01:56:55.857 | -0.5   |          4 |
| point_z  | 2015-352T01:56:52.270 | -9.703 |          1 |
| point_z  | 2015-360T07:20:32.010 | 0.0    |          2 |
+----------+-----------------------+--------+------------+

以上查询效果很好

我遇到问题的最后一个问题是 &#34;显示所有内容,除了省略第一个&#39; 之外,删除每个param_id重复的值 (此值将被视为默认值并且不会#39; t需要显示)&#34;

问题: 什么是查询只会省略&#39; point_y&#39;此查询中的一行,因为它只有1&#39;值&#39; (-0.5)在此时间范围内?

更新

有计数(param_id)&gt; 1不起作用......

mysql> select param_id,time,value,count(*) as replicates  
       from PARAMETERS where  
       param_id like 'point_%' and 
       time >= '2015-352T01:56:52.270' and 
       time <= '2015-360T07:20:32.010' 
       group by value,param_id having count(param_id)>1  
       order by param_id,time;
+----------+-----------------------+-------+------------+
| param_id | time                  | value | replicates |
+----------+-----------------------+-------+------------+
| point_x  | 2015-360T07:20:32.010 | 1.57  |          2 |
| point_y  | 2015-352T01:56:55.857 | -0.5  |          4 |
| point_z  | 2015-360T07:20:32.010 | 0.0   |          2 |
+----------+-----------------------+-------+------------+

&#34;有计数&#34;在一个子选择内?也不好......

mysql>  select * from (select param_id,time,value  from PARAMETERS where 
                 param_id like 'point_%' and 
                 time >= '2015-352T01:56:52.270' and 
                 time <= '2015-360T07:20:32.010' 
                 group by value,param_id order by param_id,time) as t1 
        having (count(t1.param_id)>1);
+----------+-----------------------+-------+
| param_id | time                  | value |
+----------+-----------------------+-------+
| point_x  | 2015-352T01:56:52.270 | 0.0   |
+----------+-----------------------+-------+

可能的解决方案(需要优化)

以下连接查询可以正常工作,因为我可以使用一些服务器端代码,但它会使查询时间加倍。有没有办法优化这个?

mysql> select t1.param_id,t1.time,t1.value,t2.param_id_cnt 
       from (
          select param_id,time,value 
          from PARAMETERS 
               where param_id like 'point_%' and 
               time >= '2015-352T01:56:52.270' and 
               time <= '2015-360T07:20:32.010' 
               group by param_id, value 
               order by param_id,time ) t1 
       join (
          select *,count(X.param_id) as param_id_cnt 
          from (
               select id,param_id,time,value  
               from PARAMETERS 
                    where param_id like 'point_%' and 
                    time >= '2015-352T01:56:52.270' and 
                    time <= '2015-360T07:20:32.010' 
                    group by param_id, 
                    value order by param_id,time ) X 
               group by X.param_id) t2 
        on t1.param_id=t2.param_id;


+----------+-----------------------+--------+--------------+
| param_id | time                  | value  | param_id_cnt |
+----------+-----------------------+--------+--------------+
| point_x  | 2015-352T01:56:52.270 | 0.0    |            2 |
| point_x  | 2015-360T07:20:32.010 | 1.57   |            2 |
| point_y  | 2015-352T01:56:55.857 | -0.5   |            1 |
| point_z  | 2015-352T01:56:52.270 | -9.703 |            2 |
| point_z  | 2015-360T07:20:32.010 | 0.0    |            2 |
+----------+-----------------------+--------+--------------+

1 个答案:

答案 0 :(得分:0)

首先,您只需从&#34中获取具有1个以上不同值的param_id;显示删除重复的所有内容&#39;每个param_id&#34; 查询然后再次将其与该查询一起加入过滤的param_id

SELECT 
    a.param_id, b.time, b.value
FROM (
    select param_id
    from PARAMETERS 
    where 
       param_id like 'point_%' and 
       time >= '2015-352T01:56:52.270' and 
       time <= '2015-360T07:20:32.010' 
    group by param_id
    having count(distinct value) > 1
    ) a
JOIN (
    select param_id,time,value
    from PARAMETERS 
    where 
       param_id like 'point_%' and 
       time >= '2015-352T01:56:52.270' and 
       time <= '2015-360T07:20:32.010' 
    group by value,param_id order by param_id, time
    ) b ON  
        a.param_id = b.param_id
ORDER BY a.param_id, b.time

评论后编辑:

不幸的是,MySQL不支持用于定义公用表表达式的WITH子句。防止执行相同查询两次的一种方法是创建临时表并在该查询中使用它。您可以在MySQL here中阅读有关临时表的更多信息。

CREATE TEMPORARY TABLE tmp_parameters AS (
    select param_id,time,value
    from PARAMETERS 
    where 
       param_id like 'point_%' and 
       time >= '2015-352T01:56:52.270' and 
       time <= '2015-360T07:20:32.010' 
    group by value,param_id order by param_id, time
);

调整后的查询将如下所示:

SELECT 
    a.param_id, b.time, b.value
FROM (
    select param_id
    from tmp_parameters
    group by param_id
    having count(distinct value) > 1
    ) a
JOIN tmp_parameters b ON a.param_id = b.param_id
ORDER BY a.param_id, b.time