Прежде всего вам нужна модель ценников, которая проста:
price_labels
id | label
1 | Price
2 | Discount
3 | Tax
Затем слегка измененная версия примера таблицы, которую вы дали:
products_prices
price_id|product_id|label_id|divider|value
1 10 1 1 20
2 10 2 100 -25
3 10 3 100 10
Здесь я просто заменил метку соответствующим id из таблицы price_labels в качестве внешнего ключа. Кроме того, я пропустил поле type , которое тривиально, поскольку значение может быть положительным или отрицательным числом с плавающей точкой. Я добавил столбец делителя, чтобы включить процентный параметр. Я думаю, что так легче читать и так, поскольку вы говорите (и думаете) «минус двадцать пять процентов», а не 0,25.
Теперь часть выражения "абстракция" немного сложнее, и может быть много решений.
price_expressions
product_id | date_from | date_until | expression
10 |2011-11-02 04:00:00 |2011-11-12 04:00:00 | (SELECT divider*value from
products_prices
WHERE product_id=%PRODUCT_ID%
AND label_id=1)*
(SELECT 1+value/divider from products_prices
where product_id=%PRODUCT_ID% AND
label_id=2)*
(SELECT 1+value/divider from products_prices
where product_id=%PRODUCT_ID% AND
label_id=3)
В поле выражения вы можете сохранить сложный оператор SQL, в котором вы можете просто заменить заполнитель% PRODUCT_ID% значением product_id из той же строки:
SELECT REPLACE(expression,'%PRODUCT_ID%',CAST(product_id AS char))
AS price_expression FROM price_expressions
WHERE product_id = 10 AND date_from>=DATE_OF_PURCHASE
AND date_until<=DATE_OF_PURCHASE
Существует два возможных варианта, как я это вижу:
- Вы можете изменить условие product_id =% PRODUCT_ID% и label_id = N , указав только price_id = N, поскольку оно уже сохранено в таблице products_prices
- Вы можете использовать другой формат выражения, например, % PRICE_ID_1% *% PRICE_ID_2 и выполнять подстановки и вычисления на уровне приложения, а не непосредственно в SQL
Надеюсь, это поможет.