运算符中的sql,每个元素的限制和偏移量

时间:2017-01-06 09:20:19

标签: mysql sql subquery limit offset

目前我使用多个查询来获取类似的数据:

SELECT value1, value2 FROM table WHERE id=10 ORDER BY date DESC LIMIT 1 OFFSET 1

我现在想要一个像这样的独特查询:

SELECT value1, value2 FROM table WHERE id IN (10,12) ORDER BY date DESC LIMIT 2 OFFSET 1

但很明显它因为偏移参数而无法工作,所以我无法正常工作,我想我可以使用一些子查询,但Mysql的版本是{{1在子查询中不允许限制或偏移...

示例数据:

5.1.x

我想举个例子(对于每个ID,我希望得到倒数第二个数据):

id value1 value2 date
1   64.2   10.1  2017-01-06 10:20:00
2   20.2   2.5   2017-01-06 10:19:30
2   20.3   2.4   2017-01-06 10:19:10
1   63.8   10.0  2017-01-06 10:19:00
3   20.0   9.9   2017-01-06 10:18:30
2   20.1   2.4   2017-01-06 10:18:00
3   19.9   5.0   2017-01-06 10:17:59

甚至可能吗?

2 个答案:

答案 0 :(得分:3)

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
( id INT NOT NULL
, value1 DECIMAL(5,2) NOT NULL
, value2 DECIMAL(5,2) NOT NULL
, date DATETIME NOT NULL
, PRIMARY KEY(id,date)
);

INSERT INTO my_table VALUES
(1   ,64.2   ,10.1  ,'2017-01-06 10:20:00'),
(2   ,20.2   ,2.5   ,'2017-01-06 10:19:30'),
(2   ,20.3   ,2.4   ,'2017-01-06 10:19:10'),
(1   ,63.8   ,10.0  ,'2017-01-06 10:19:00'),
(3   ,20.0   ,9.9   ,'2017-01-06 10:18:30'),
(2   ,20.1   ,2.4   ,'2017-01-06 10:18:00'),
(3   ,19.9   ,5.0   ,'2017-01-06 10:17:59');

这是一个想法。它不能很好地扩展,并且仅适用于第二高结果的特定示例,因此它不能扩展到更一般的情况:

SELECT x.* 
  FROM my_table x 
  JOIN 
     ( SELECT a.id
            , MAX(a.date) date 
         FROM my_table a 
        WHERE date NOT IN (SELECT MAX(date) FROM my_table WHERE id = a.id GROUP BY id) 
        GROUP 
           BY id
     ) y 
    ON y.date = x.date 
   AND y.id = x.id;
+----+--------+--------+---------------------+
| id | value1 | value2 | date                |
+----+--------+--------+---------------------+
|  1 |  63.80 |  10.00 | 2017-01-06 10:19:00 |
|  2 |  20.30 |   2.40 | 2017-01-06 10:19:10 |
|  3 |  19.90 |   5.00 | 2017-01-06 10:17:59 |
+----+--------+--------+---------------------+

这是另一个想法。它可以很好地扩展,并且很容易扩展到更一般的情况(所以i = 3,比如说):

SELECT id
     , value1
     , value2
     , date 
  FROM 
     ( SELECT x.*
            , CASE WHEN @prev=id THEN @i:=@i+1 ELSE @i:=1 END i
            , @prev := id prev 
         FROM my_table x
            , ( SELECT @prev:=null,@i:=0) vars ORDER BY id,date DESC ) a 
        WHERE i = 2;
+----+--------+--------+---------------------+
| id | value1 | value2 | date                |
+----+--------+--------+---------------------+
|  1 |  63.80 |  10.00 | 2017-01-06 10:19:00 |
|  2 |  20.30 |   2.40 | 2017-01-06 10:19:10 |
|  3 |  19.90 |   5.00 | 2017-01-06 10:17:59 |
+----+--------+--------+---------------------+

答案 1 :(得分:-1)

据我所知,您希望将limit和offset独立应用于查询的两个不同子集。在大多数RDBMS中,您可以使用某种子查询来执行此操作。在其他关系数据库系统中用于执行此操作的主要功能是窗口函数和公用表表达式。 MySQL尚不支持这些功能。

好的,所以你的主要问题是MySQL不支持窗口函数或公用表表达式。如果支持这些功能中的任何一个,就没有问题。

绕过这个限制将是丑陋的。没有一个非常好,优雅的方式来做到这一点。但是,您可以通过以下两种方式之一解决此问题。

第一种是使用临时表来构建结果,第二种是通过创建视图来模拟公用表表达式。