2013-08-16 6 views
5

はのは、私は次のような表があるとしましょう:アイテムのSELECT行

Item   Description   Time 
-----  -----------   ----- 
ItemA1  descript    08-16-2013 00:00:00 
ItemA2  descript    08-16-2013 00:00:00 
ItemA3  descript    08-16-2013 00:00:00 
. 
. 
ItemAN  descript    08-16-2013 00:00:00 

ItemB1  descript    08-13-2013 00:00:00 
ItemB2  descript    08-13-2013 00:00:00 
ItemB3  descript    08-13-2013 00:00:00 
. 
. 
ItemBN  descript    08-13-2013 00:00:00 
. 
. 
. 
ItemX1  descript    01-13-2012 00:00:00 
ItemX2  descript    01-13-2012 00:00:00 
ItemX3  descript    01-13-2012 00:00:00 
. 
. 
ItemXN  descript    01-13-2012 00:00:00 

グループが定期的に追加されます。アイテムのグループが追加されると、それらはすべて同じ「時間」フィールドで追加されます。 「時間」は基本的に、そのアイテムグループのユニークなインデックスとして機能します。

2番目に時間のかかるアイテムのグループを選択したいと考えています。この例では、私のクエリは "B"項目をプルする必要があります。私は "A"項目を選択するためにmax(time)を行うことができると知っていますが、私はどのように2番目のことをするのか分かりません。

My "Time"列は、何かを意味する場合はTIMESTAMPとして格納されます。

+0

インデックスの利用可能性に応じて、LIMITのパフォーマンスが低下する可能性があるため、MAXとLIMIT/ORDER BYソリューションの両方をテストする必要があります。 http://stackoverflow.com/questions/426731/min-max-vs-order-by-and-limit –

+0

[2番目に大きな値を見つけるのに最も単純なSQLクエリは何ですか?](http:// stackoverflow .com/questions/32100/what-is-the-the-the-the-simple-sql-query-to-second-largest-value) – heretolearn

答えて

13

あなたのような何かを試すことができます。

SELECT MAX(Time) 
FROM yourTable 
WHERE Time < (SELECT MAX(Time) FROM yourTable) 

SQLFiddle Demo

+0

なぜdownvoteですか? – DarkAjax

+0

いいえ、sqlのフィドルボタンを+1しますが、クエリでアイテムは表示されませんが、ちょうど時間が –

+0

@DarkAjaxです。この解決方法はまったく変わりません。あなたはどのように3位を選んでいますか?または、4th、5th、6​​th、nth? – Pacerier

7

一つのアプローチ:これは、第二の「最大を返すために(メートルのエイリアスを割り当て)インライン・ビューを使用しています

SELECT t.* 
FROM mytable t 
JOIN (SELECT l.time 
      FROM mytable l 
     GROUP BY l.time 
     ORDER BY l.time DESC 
     LIMIT 1,1 
    ) m 
    ON m.time = t.time 

時間値。 GROUP BYは私たちに別個のリストを与え、ORDER BY DESCは最新のものを入れ、 "トリック"はLIMITであり、2番目の行を返します。

この時間値を使用すると、元のテーブルに戻って、一致する時間値を持つすべての行を取得できます。LIMIT(m、n)=(最初のm行をスキップして次のn行を返します。


パフォーマンスは、先頭の列がtimeのインデックスで強化されます。 (MySQLは "Using filesort"オペレーションを避け、インラインビュークエリの結果をかなり素早く得ることができるはずです)。 2番目に新しい時刻が、昔の一定数以上になることはありませんパフォーマンスを傷つけることはありません。

WHERE l.time > NOW() + INTERVAL -30 DAYS 

しかし、それは追加して、それはtimeだ場合、クエリは「第二の最新」のグループを返しません30日以上前です。

timeの先頭の列のインデックスがない場合は、2番目の最新のアプローチ(他の回答に記載されている方法)が高速になる可能性がありますが、パフォーマンスは実際のテストで最もよく評価されます。先行する列のインデックスは、MAX()アプローチも高速化します。

私が提供したクエリは、LIMIT節を変更することで、4番目の最新、42番目の最新のものなどを簡単に拡張できます... LIMIT(3,1),LIMIT(41,1)など

+0

+1ベストアンサー。 –

+0

*注:*この回答のクエリは、MySQLの他の商用データベースでサポートされていないMySQL固有の 'LIMIT'構文を使用しています。 – spencer7593

+0

サブクエリのLIMIT構文は、以前のバージョンのMySQLではサポートされていません。 – Manu

1
SELECT T1.ITEM 
FROM YOURTABLE T1 
WHERE T1.TIME = (SELECT MAX(T2.TIME) 
        FROM YOURTABLE T2 
        WHERE T2.TIME < (SELECT MAX(T3.TIME) 
             FROM YOURTABLE T3 
            ) 
       ) 
0

このような本当に簡単なものはこれがあなたの第二の最大の時間を与える必要があり

select * from my-table where time = 
    (Select top 1 time 
    from (select top 2 time from my-table order by time desc) 
    order by time asc) 
+0

'TOP'はMicrosoft SQL Server構文であり、MySQLではサポートされていません。 – spencer7593

+0

これは、ANSI準拠のMAX()アプローチを採用する理由です。 –

4

を動作するはずです:

SELECT time FROM table GROUP BY time ORDER BY time DESC LIMIT 1,1 
1

N番目の最高......第四、第2、第3ゲット次のクエリを使用して値:

SELECT MIN(value) from yourTable WHERE value IN(SELECT TOP N value FROM yourTable ORDER BY value DESC) 

Nを番号で置き換えます。つまり、2番目に高い値の場合はN = 2、3番目の値の場合はN = 3などとなります。だから、二番目に高い値を使用するため:ここ

SELECT MIN(value) from yourTable WHERE value IN(SELECT TOP 2 value FROM yourTable ORDER BY value DESC) 
0

は、私はあなたの問題のために働くべきだと思い、別のソリューションです:

CREATE TEMPORARY TABLE xHighest AS (SELECT DISTINCT Time FROM `my-table` ORDER BY Time DESC LIMIT 1,1); 

SELECT * FROM `my-table` JOIN xHighest ON (my-table.Time = xHighest.Time); 

第二、第三、...最高値がすべき場合は、選択することができますLIMITの最初のパラメータを変更することによって使用できます。

0

MYSQL:限界塩基溶液

例:レコード1、2、3、4、5

LIMIT 2,1それはLIMIT 1,1リターンとして、第3最大数を返すことを意味2番目に高い数字など

SELECT rc。 rc_officer_id FROM recovery_complain_officer rc ORDER BY rc。 rc_officer_id DESC LIMIT 2,1