2012-06-17 4 views
0

У меня есть таблица, которая содержит показания различных счетчиковПолучение второй последней записи из таблицы тузд

+-----------+---------+---------+---------+---------------------+ 
| idReading | idMeter | index | usage | dateOfReading  | 
+-----------+---------+---------+---------+---------------------+ 
|  671 |  189 | 884.000 | 441.000 | 2012-06-01 00:00:00 | 
|  672 |  190 | 170.000 | 82.000 | 2012-06-01 00:00:00 | 
|  584 |  190 | 88.000 | 88.000 | 2012-05-01 00:00:00 | 
|  583 |  189 | 443.000 | 443.000 | 2012-05-01 00:00:00 | 
+-----------+---------+---------+---------+---------------------+ 

В моем приложении мне нужно иметь в наличии как текущее значение (которое может или не может присутствовать) и предыдущее чтение, которое может быть от нескольких месяцев назад. Поэтому я могу прочитать настоящее чтение в июле, но предыдущее чтение может состояться в апреле.

Я использую следующий запрос, чтобы получить предыдущее чтение:

SELECT * FROM (
    SELECT Reading.idMeter, Reading.usage, Reading.`Index`, Reading.dateOfReading 
    FROM meterReadings AS Reading 
    WHERE Reading.idMeter IN (189,190) 
    AND Reading.dateOfReading < '2012-07-31' 
    ORDER BY Reading.dateOfReading DESC) AS OrderendReading 
GROUP BY OrderendReading.idMeter 

Это работает прилично, но я не рад, что я использую ОТБОРНОЕ в другой SELECT, как я боюсь, как таблица становится все больше и больше запрос займет больше времени и дольше. Есть ли другой способ получить предыдущее чтение? Или есть способ сделать этот запрос более эффективным?

Или, в идеале, есть как настоящее чтение, так и предыдущее в том же запросе?

спасибо.

+1

вы пытались с помощью [ 'LIMIT'] (Http: //dev.mysql. ком/док/RefMan/5,1/о/select.html)? – Jason

+0

Я попробовал только внутренний запрос без заказа и использования группы, но это дало мне результат только с мая, даже не июня, поэтому я не вижу, как может помочь LIMIT. – eXtenZy

+0

используйте 'LIMIT' для внешнего запроса. Вам просто нужны первые два результата, верно? – Jason

ответ

0

Вчера я только что обнаружил «Аналитические функции», и я уверен, что они охватывают этот тип требований. Дайте ему Google, некоторые учебники на Youtube тоже.

+0

На самом деле есть пример: http://stackoverflow.com/questions/2491063/predefined-function-or-method-available-to-get-second-highest-salary-from-an-emp – Tams

+0

Это больше комментария, чем ответа. Также они недоступны в MySQL (все же). Использование переменной incrementing, используемой в [недавнем ответе на мой вопрос] (stackoverflow.com/questions/10980957/#10983910), является единственным способом, который я знаю, чтобы эмулировать функции ROW_NUMBER() других СУБД. – GarethD

+0

Да, я попытался прокомментировать, но у меня нет такой опции, если нет ответа. Любые идеи, почему это может быть? Это ограничение для новых членов? Я только вчера присоединился. – Tams

0

Попробуйте это:

SELECT 
    Reading.idMeter, 
    Reading.usage, 
    Reading.`Index`, 
    (Select dateOfReading from meterReading order by dateOfReading desc limit 1,1) 
FROM meterReadings AS Reading 
GROUP BY Reading.idMeter; 
+0

Это дает мне чтение только с одного метра. Мне нужны показания всех счетчиков в разделе 'IN'. – eXtenZy

+0

Вы хотите, чтобы предыдущее чтение каждого метра?> –

+0

Да, для каждого счетчика я указываю в предложении 'IN'. – eXtenZy

1

Я думаю, коррелированные подзапросы бы добиться того, что вы после:

SELECT Reading.idMeter, 
     Reading.usage, 
     Reading.`Index`, 
     Reading.dateOfReading, 
     ( SELECT mr.Usage 
      FROM MeterReadings AS mr 
      WHERE mr.idMeter = Reading.idMeter 
      AND  mr.DateOfReading < Reading.DateofReading 
      ORDER BY DateOfReading DESC 
      LIMIT 1 
     ) AS PreviousReadingUsage 
FROM meterReadings AS Reading, 
WHERE Reading.idMeter IN (189,190) 
AND  Reading.dateOfReading < '2012-07-31' 
ORDER BY Reading.dateOfReading DESC 
Смежные вопросы