Страница 1 из 1

Хранение цены на товар

Добавлено: 19 окт 2006, 14:57
CyberMax
Дано: товар и переменный атрибут - цена.
Задание: как определить цену товара в произвольный день?

Самое простое решение: табличка с полями "Дата" и "Цена".
Запрос определения:

Код: Выделить всё

SELECT FIRST 1
    PRICE
FROM
    T_PRICE
WHERE
    :DATE >= DATE_PRICE
ORDER BY
    DATE_PRICE DESC
Есть ли другие варианты решения данной задачи?

Re: Хранение цены на товар

Добавлено: 19 окт 2006, 19:31
nicolas
CyberMax писал(а):Дано: товар и переменный атрибут - цена.
Задание: как определить цену товара в произвольный день?

Самое простое решение: табличка с полями "Дата" и "Цена".
Запрос определения:

Код: Выделить всё

SELECT FIRST 1
    PRICE
FROM
    T_PRICE
WHERE
    :DATE >= DATE_PRICE
ORDER BY
    DATE_PRICE DESC
Есть ли другие варианты решения данной задачи?
Самый ИМХО классический вариант, сами таким пользуемся. Только самую первую запись пишем на 01.01.1980, потому как у клиентов привычка заводить карточку нового товара прямо из накладной, которая уже создана на дату.

Добавлено: 20 окт 2006, 10:52
WildSery
Если в простом варианте - я бы сделал так (опустим валюты и типы прайс-листов):

Код: Выделить всё

CREATE TABLE PRICEARCHIVE (
    GOODSID  INTEGER NOT NULL,
    PRICE    NUMERIC(9,2),
    DATEBEG  DATE NOT NULL,
    DATEEND  DATE DEFAULT '31.01.2099' NOT NULL);

ALTER TABLE PRICEARCHIVE ADD CONSTRAINT PK_PRICEARCHIVE PRIMARY KEY (GOODSID, DATEBEG, DATEEND);

select Price
  from PriceArchive
  where GoodsId=:GoodsId and :ActDate between DateBeg and DateEnd
Цена хранится непересекающимися периодами. Т.е. не 1 день = 1 цена, а может быть 1 цена в течение месяца.
При определённых условиях (десятки прайс-листов с небольшими ежедневными изменениями) экономит море места.

Добавлено: 20 окт 2006, 11:46
Andrew Sagulin
WildSery писал(а): Цена хранится непересекающимися периодами. Т.е. не 1 день = 1 цена, а может быть 1 цена в течение месяца.
При определённых условиях (десятки прайс-листов с небольшими ежедневными изменениями) экономит море места.
Дык, и у CyberMax тоже одна цена на период. И экономно получается, так как нет dateend. И работать, скорее всего, будет быстрее, так как не надо считывать дополнительный индекс по dateend (cоставной индекс по (datebeg ,dateend) здесь тоже не поможет).

Добавлено: 20 окт 2006, 13:27
WildSery
Andrew Sagulin писал(а):Дык, и у CyberMax тоже одна цена на период. И экономно получается, так как нет dateend.
Вообще он не говорил, сохраняется ли цена каждый день или только когда меняется. Если когда меняется - то тут не предусмотрена ситуация, когда цены в конкретный период нет вообще.
Andrew Sagulin писал(а):И работать, скорее всего, будет быстрее, так как не надо считывать дополнительный индекс по dateend (cоставной индекс по (datebeg ,dateend) здесь тоже не поможет).
Конкретный индекс я написал в примере. А вместо бла-бла возьми да попробуй. Быстрее не будет, 1 запись по индексу выбирается.

Добавлено: 20 окт 2006, 18:30
CyberMax
Хорошо, напишу подробней. Дабы замаскироваться, возьму в качестве примера стоимость проезда на автобусе.
Получается следующая таблица:
Дата - Цена
01.01.2004 - 5 рублей
01.01.2005 - 6 рублей
5.06.2005 - 7 рублей
01.01.2006 - 8 рублей
То есть периодически происходит изменение стоимости на неопределенный срок.

Мне надо определить, зная дату, стоимость билета в конкретный день.
Минус - если дата меньше 2004 г., то результат неопределен. Но такие случаи проверяются в клиенте. Плюс: последняя цена не ограничена конкретным сроком (в примере WildSery ограничение по дате. Там, кстати, имелось ввиду 31 декабря, а не января? :) ).

Первоначальное решение задачи не показалось мне лучшим, поэтому и спросил. Ведь подобная проблема наверняка кем-то уже решалась.

Добавлено: 20 окт 2006, 18:39
WildSery
CyberMax писал(а):Там, кстати, имелось ввиду 31 декабря, а не января?
Собственно, без разницы. Первое что из головы набилось. Главное, чтобы была практически недостижимая дата.

Если у тебя случай в точности, как описал, то да. Хватит нисходящего индекса по дате.

Вот только товар - это не билет. Он имеет тенденцию исчезать из продажи и появляться вновь.

Добавлено: 20 окт 2006, 21:58
nicolas
WildSery писал(а):Вот только товар - это не билет. Он имеет тенденцию исчезать из продажи и появляться вновь.
А насколько правильно в один регистр сводить несколько признаков: цена товара и его наличие в продаже?

ЗЫ. А по поводу цены "до первой записи" - можно на клиенте разруливать, а можно первую запись в триггере ставить на далекое прошлое, например 01.01.1980. И разруливать не надо.

Добавлено: 21 окт 2006, 18:35
CyberMax
Этого товара - бесконечность. Поэтому мне не надо определять, сколько его осталось. Мне надо только знать, сколько этого товара (билетов :)) было реализовано за день и по какой цене. Потому и фигурировала только его стоимость.

Добавлено: 23 окт 2006, 12:59
WildSery
nicolas писал(а):А насколько правильно в один регистр сводить несколько признаков: цена товара и его наличие в продаже?
Это следствие, не путай. По отсутствию цены можно определить отсутствие товара, но цель такого хранения не в этом.
Какая по-твоему должна быть цена в этот период?

Добавлено: 23 окт 2006, 23:57
nicolas
WildSery писал(а):
nicolas писал(а):А насколько правильно в один регистр сводить несколько признаков: цена товара и его наличие в продаже?
Это следствие, не путай. По отсутствию цены можно определить отсутствие товара, но цель такого хранения не в этом.
Какая по-твоему должна быть цена в этот период?
ИМХО цена должна быть равна ближайшему значению в прошлом, как уже здесь выше говорилось... По крайней мере у нас так

Добавлено: 25 янв 2007, 14:14
dsd_corp
WildSery писал(а):По отсутствию цены можно определить отсутствие товара, но цель такого хранения не в этом.
Какая по-твоему должна быть цена в этот период?
а null тебе зачем дан?

пример данных:
15.10.2004 -> $20
01.01.2005 -> null
03.02.2005 -> $18

итого имеем: с 01.01.2005 по 03.02.2005 цены на товар не было, или по-твоему: пропадал из продажи.