SQL: получить только те записи, значение которых изменилось - PullRequest
6 голосов
/ 27 марта 2009

Извините за невзрачный заголовок. Я буду редактировать, как мы идем вместе.

У меня есть таблица RateTable:

| Code   |  Date     |   Rate  |

  B001     2009-01-01   1.05
  B001     2009-01-02   1.05
  B001     2009-01-03   1.05
  B001     2009-01-04   1.05
  B001     2009-01-05   1.06
  B001     2009-01-06   1.06
  B001     2009-01-07   1.06
  B001     2009-01-08   1.07

Запись на каждый день есть, но курс редко меняется. Могу ли я написать запрос SQL, который будет возвращать только те строки, в которых происходит изменение скорости Я использую SQLServer

Ответы [ 7 ]

15 голосов
/ 27 марта 2009

Если я правильно понял, вы ищете не измененные строки, а строки, в которых курс меняется по сравнению с предыдущей датой. Этот запрос или что-то вроде этого должно сделать это:

SELECT  r1.Code, r1.Date, r1.Rate
FROM    RateTable r1
WHERE   r1.Rate <> (SELECT TOP 1 Rate
                   FROM    RateTable
                   WHERE   Date < r1.Date
                   ORDER BY Date DESC)
3 голосов
/ 27 марта 2009

Если ваша СУБД поддерживает аналитические функции, то оптимальный метод почти наверняка таков:

select code, date, rate, last_rate
from
(
select code,
       date,
       rate,
       lag(rate) over (partition by code order by date) last_rate
from   ratetable
) my_tb
where  my_tb.rate != my_tb.last_rate
0 голосов
/ 27 марта 2009

как насчет этого подхода, ребята?

добавьте битовый столбец с именем ChangedSinceLastRead, установите его равным 1 каждый раз, когда вы изменяете значение в этой таблице, и в вашем запросе выбора читайте «SELECT * FROM Rate WHERE ChangedSinceLastRead = 1»

после этого запроса на выборку запускается другой запрос "UPDATE Rate SET ChangedSinceLastRead = 0"

, хотя для этого вам нужно запустить 1 дополнительный запрос на обновление, вам не нужно вычислять даты по вашему выбору, и хранилище таблицы занимает меньше места (поскольку бит меньше даты / времени)

просто еще один способ решить эту проблему ;-) Мне бы очень хотелось увидеть, как это влияет на производительность, а также предложенный выше подход к дате и времени

0 голосов
/ 27 марта 2009

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

Тем не менее, этот запрос, или что-то близкое, должно выполнить то, что вы просите:

select rt.Code, MIN(rt.Date), rt.Rate
from RateTable rt
group by rt.Code, rt.Rate

edit : извините, измените максимум на min

0 голосов
/ 27 марта 2009

Если вы добавите новый столбец «LastChangedDate» и отследите последнее чтение в другой таблице (т. Е. LastReadedValues), то вы сможете легко отследить изменения.

0 голосов
/ 27 марта 2009

Я бы добавил столбец [ModifiedDate] в вашу таблицу и обновил бы его значение каждый раз, когда новая запись вставляется или обновляется. Тогда вы сможете получить данные из таблицы на основе этого столбца:

SELECT * FROM [YourTable] WHERE [ModifiedDate] > '2008-01-20 10:20'
0 голосов
/ 27 марта 2009

Добавить новый столбец, который будет DateTime и отслеживать, когда скорость изменилась. Тогда вы можете просто вернуть любые столбцы, которые DateModified> = x ... Где x - последний раз, когда вы проверяли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...