2015-04-15 2 views
0

У меня есть две таблицы:возвращает последнюю строку, которая удовлетворяет условию в SQL

Meter

ID   SerialNumber 
======================= 
1   ABC1 
2   ABC2 
3   ABC3 
4   ABC4 
5   ABC5 
6   ABC6 

RegisterLevelInformation

ID   MeterID ReadValue Consumption PreviousReadDate ReadType 
============================================================================ 
1   1   250   250   1 jan 2015   EST 
2   1   550   300   1 feb 2015   ACT 
3   1   1000   450   1 apr 2015   EST 
4   2   350   350   1 jan 2015   EST 
5   2   850   500   1 feb 2015   ACT 
6   2   1000   150   1 apr 2015   ACT 
7   3   1500   1500   1 jan 2015   EST 
8   3   2500   1000   1 mar 2015   EST 
9   3   5000   2500   4 apr 2015   EST 
10   4   250   250   1 jan 2015   EST 
11   4   550   300   1 feb 2015   ACT 
12   4   1000   450   1 apr 2015   EST 
13   5   350   350   1 jan 2015   ACT 
14   5   850   500   1 feb 2015   ACT 
15   5   1000   150   1 apr 2015   ACT 
16   6   1500   1500   1 jan 2015   EST 
17   6   2500   1000   1 mar 2015   EST 
18   6   5000   2500   4 apr 2015   EST 

Я пытаюсь группе метр сериала и вернуть последнюю фактическую дату чтения для каждого из счетчиков, но я не уверен, как это сделать. Вот SQL у меня до сих пор:

select a.SerialNumber, ReadTypeCode, MAX(PreviousReadDate) from Meter as a 
left join RegisterLevelInformation as b on a.MeterID = b.MeterID 
where ReadType = 'ACT' 
group by a.SerialNumber,b.ReadTypeCode, PreviousReadDate 
order by a.SerialNumber 

Я не могу показаться, чтобы получить функцию MAX вступили в силу в возвращении только последнюю строку фактического чтения и возвращает все даты и тот же метр сериал отображается несколько раз.

Если я использую следующий SQL:

select a.SerialNumber, count(*) from Meter as a 
left join RegisterLevelInformation as b on a.MeterID = b.MeterID 
group by a.SerialNumber 
order by a.SerialNumber 

, то каждый последовательный показан только один раз. Любая помощь будет принята с благодарностью.

+3

Он возвращает все даты чтения, потому что вы включили эту колонку в предложение 'GROUP BY'. Вытащите его и посмотрите, что вы получите. –

+0

Имеет ли 'предыдущийReadDate' столбец данных даты? –

+1

Какой тип 'rdbms' вы используете? – sgeddes

ответ

1

Как @PaulGriffin сказал в своем комментарии, вам нужно удалить столбец PreviousReadDate из вашего предложения GROUP BY.

Почему вы испытываете подобное поведение?

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

То, что вы хотели достичь

Получить MAX значение PreviousReadDate для каждой пары (SerialNumber,ReadTypeCode). Так вот что должен включать ваш пункт GROUP BY.

select a.SerialNumber, ReadTypeCode, MAX(PreviousReadDate) from Meter as a 
left join RegisterLevelInformation as b on a.MeterID = b.MeterID 
where ReadType = 'ACT' 
group by a.SerialNumber,b.ReadTypeCode 
order by a.SerialNumber 

Правильный SQL-запрос для того, что вы хотите.

пример Разница

ID   MeterID ReadValue Consumption PreviousReadDate ReadType 
============================================================================ 
1   1   250   250   1 jan 2015   EST 
2   1   550   300   1 feb 2015   ACT 
3   1   1000   450   1 apr 2015   EST 

Здесь, если применить запрос с группировкой по 3 колонки вы получите результат:

SerialNumber | ReadTypeCode | PreviousReadDate 
    ABC1  | EST  | 1 jan 2015 -- which is MAX of 1 value (1 jan 2015) 
    ABC1  | ACT  | 1 feb 2015 
    ABC1  | EST  | 1 apr 2015 

Но вместо того, чтобы, когда вы только группа по SerialNumber,ReadTypeCode это даст результат (с учетом данных о выборке, которые я опубликовал):

SerialNumber | ReadTypeCode | PreviousReadDate 
    ABC1  | EST  | 1 apr 2015 -- which is MAX of 2 values (1 jan 2015, 1 apr 2015) 
    ABC1  | ACT  | 1 feb 2015 -- which is MAX of 1 value (because ReadTypeCode is different from the row above 

Объяснение вашего второго запроса

В этом запросе - вы правы, действительно - каждый последовательный показан только один раз.

select a.SerialNumber, count(*) from Meter as a 
left join RegisterLevelInformation as b on a.MeterID = b.MeterID 
group by a.SerialNumber 
order by a.SerialNumber 

Но этот запрос будет производить вам странные результаты вы не ожидаете, если добавить группировку по нескольким столбцам (которые вы сделали в первом запросе - попробовать это сами).

+0

Спасибо за очень четкий ответ, очень благодарен Я теперь понимаю, что на самом деле делает группа по функциям !!! :) Я пробовал продолжить это, объявив MAX (PreviousReadDate) в качестве readdate и используя это в функции where, чтобы я мог проверить тех, кто читал между сегодняшним днем ​​и 6 месяцев назад – Jay

+1

Рад, что я мог бы помочь с базовым пониманием - остальное ваш идти :) Вы также можете принять ответ, если вы чувствуете, что это именно то, что вам нужно. –

1

Вам необходимо удалить PreviousReadDate из предложения Group By. Это то, что ваш запрос должен выглядеть следующим образом:

select a.SerialNumber, ReadTypeCode, MAX(PreviousReadDate) from Meter as a 
left join RegisterLevelInformation as b on a.MeterID = b.MeterID 
where ReadType = 'ACT' 
group by a.SerialNumber,b.ReadTypeCode 
order by a.SerialNumber 

Чтобы понять, каким образом группа пунктом работает, когда вы упоминаете несколько столбцов, перейдите по этой ссылке: Using group by on multiple columns

Вы поймете, что не так с вашим запросом и почему он возвращает все даты, и один и тот же серийный номер индикатора отображается несколько раз. Удачи! Kudos! :)

Смежные вопросы