Оператор Postgresql CASE - могу ли я использовать возвращаемое значение CASE в моем SELECT? - PullRequest
11 голосов
/ 31 октября 2011

У меня есть база данных продуктов с несколькими таблицами для хранения цен (из-за цены по умолчанию и необязательной цены переопределения для цвета продукта), и в моем запросе есть операторы CASE, чтобы получить * Оригинальная цена товара * Цена продажи товара, если он продается

Мне также нужно рассчитать СКИДКУ на продукт, если он продается. Прежде чем я попробую это, пожалуйста, посмотрите разбивку моего существующего SQL, который работает.

SELECT  p.productid, p.stylename,
CASE    WHEN (ppo.original_price IS NOT NULL) THEN ppo.original_price ELSE pp.original_price END AS final_original_price,
CASE    WHEN (ppo.original_price IS NOT NULL) THEN ppo.sale_price ELSE pp.sale_price END AS final_sale_price

FROM product p, ... etc.

Приведенный выше код работает (я упростил его), и в основном исходная цена продукта хранится в псевдониме столбца "final_original_price", а цена продажи (которая может быть NULL) возвращается как "final_sale_price".

Теперь я хочу добавить дополнительную строку в SELECT, чтобы получить скидку. Я не могу использовать существующие поля в фактической таблице, потому что я хочу, чтобы эти возвращаемые значения "final_original_price" и "final_sale_price" выполняли вычисления.

1010 *, например *

SELECT  p.productid, p.stylename,
CASE    WHEN (ppo.original_price IS NOT NULL) THEN ppo.original_price ELSE pp.original_price END AS final_original_price,
CASE    WHEN (ppo.original_price IS NOT NULL) THEN ppo.sale_price ELSE pp.sale_price END AS final_sale_price,

((final_original_price - final_sale_price) / final_original_price * 100) AS final_discount_percentage 

FROM product p, ... etc.

Выше не работает, так как Postgresql возвращает "ОШИБКА: столбец" final_original_price "не существует на символ ....."

Итак, я не могу использовать возвращаемое значение CASE. Мои вопросы о том, какое решение использовать:

1) Могу ли я действительно использовать возвращаемое значение в кейсе, как я хочу, выше? ИЛИ ЖЕ 2) Нужно ли мне снова подключать инструкцию case к моим расчетам? Это означает, что мне нужно повторить код CASE, и запрос будет выглядеть довольно длинным. Если бы мне пришлось, я бы сделал это, но мне просто интересно, есть ли лучший способ. ИЛИ ЖЕ 3) Я также мог бы хранить в базе данных дополнительное поле для хранения скидки. Эти данные будут избыточными, потому что моя CMS должна будет гарантировать, что поле обновляется всякий раз, когда обновляется цена. Однако это сохранит тяжелые вычисления (если вышеупомянутое считается тяжелым) на внешнем интерфейсе, который выполняется намного чаще, чем на CMS внутреннего интерфейса.

Вышеуказанные решения, вероятно, самые простые, но мне также интересно, если бы у меня было время, чтобы сделать это, есть ли другие решения, которые стоит рассмотреть? Например, будет ли это хорошим сценарием, чтобы написать «представление»? Лично я никогда не настраивал представление, и, насколько я понимаю, работа по выбору базы данных все еще происходит в фоновом режиме, но, если бы она была настроена, сделанный выше конечный запрос был бы проще для понимания с точки зрения разработчика.

Большое спасибо!

1 Ответ

15 голосов
/ 31 октября 2011

использование

SELECT
productid, 
stylename,
final_original_price,
final_sale_price,
((final_original_price - final_sale_price) / final_original_price * 100) AS final_discount_percentage 
FROM
(
SELECT  p.productid, p.stylename,
CASE    WHEN (ppo.original_price IS NOT NULL) THEN ppo.original_price ELSE pp.original_price END AS final_original_price,
CASE    WHEN (ppo.original_price IS NOT NULL) THEN ppo.sale_price ELSE pp.sale_price END AS final_sale_price
FROM product p, ... etc.
)

Вышесказанное делает именно то, что вы просили ... если по какой-то причине вы не хотите его использовать, то включите в расчет операторы CASE (вариант 2 из вашего вопроса).

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