2017-01-06 6 views
0

は現在、私はそのようなデータを持っている複数のクエリを使用し、各要素のオフセット:制限付きオペレータでのSQLと

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のバージョンは5.1.xですサブクエリでの制限またはオフセット...

サンプルデータ:

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 

私は(IDごとに、私はデータを最後まで二を持っているしたいのですが)、たとえばたい:

2 20.3 2.4 2017-01-06 10:19:10 
1 63.8 10.0 2017-01-06 10:19:00 
3 19.9 5.0 2017-01-06 10:17:59 

はそれも可能ですか?

+0

サンプルデータと期待される出力を示してください。 –

+0

サブクエリはどこにありますか – e4c5

+0

@ e4c5私はOPがサブクエリを含む彼の問題を解決するための代替ルートを想像していると思います。 –

答えて

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'); 

ここに1つのアイデアがあります。それはより一般的な場合に拡張することができないので、それは、うまくスケール、そして唯一の「第二最高の結果」の具体例のために働くしません:

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:[email protected]+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 | 
+----+--------+--------+---------------------+ 
+0

が正常に機能しました。優れた答え。 2番目の1つのクエリplzを説明する –

+0

任意のIDに対して単一のレコードが存在する場合、それは何を返しますか? – Susang

+0

良い質問Suraz。なぜ、それを吸い込んで見ないの? – Strawberry

-1

私はこの質問を理解しているので、制限とオフセットをクエリの2つの異なるサブセットに独立して適用したいと思っています。ほとんどのRDBMSでは、これを行うことができる何らかのサブクエリがあります。他のリレーショナル・データベース・システムでこれを行うために使用される主な機能は、ウィンドウ関数と共通表の式です。これらはMySQLでまだサポートされていません。

ここでの主な問題は、MySQLがウィンドウ関数や共通テーブル式をサポートしていないことです。これらの機能のいずれかがサポートされていれば、問題はありません。

この制限を回避することは、醜いことになるでしょう。それを行うには非常にいい、エレガントな方法はありません。しかし、これは2つの方法のいずれかによって対処できます。

最初に、一時テーブルを使用して結果を構築し、次にビューを作成して共通テーブル式をエミュレートします。

+0

または単にクエリを使用することができます – Strawberry

+0

一時的なテーブルを少し過剰生成していません(私はそれがちょうどいくつかの事をたくさんしなければならないと感じているという意味です)、私は面白いと思うかもしれないビューを見るかもしれません –

+1

私はその問題を理解しました。問題は1つのIDで制限とオフセットを取得し、同じ制限と別のクエリによってオフセットされていました。これを実際にMySQLで単一のクエリで行うことはできません。 –