Как я мог / должен написать этот SQL-запрос?

#php #sql #oracle

#php #sql #Oracle

Вопрос:

Мне нужно написать SQL-запрос, чтобы перечислить цены клиентов на наши продукты. У нас есть стандартный прайс-лист, customer_no = 0 и прайс-лист для конкретного клиента, customer_no = XXXX .

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

Чтобы получить все продукты и цены из стандартного прайс-листа

 select     prices.product_id, products.product_desc, prices.m2
from       prices, products
where      prices.product_id = products.product_id
and        prices.customer_no = 0
order by   prices.product_id asc
  

Чтобы получить все продукты и цены, которые были указаны заказчиком

 select     prices.product_id, products.product_desc, prices.m2
from       prices, products
where      prices.product_id = products.product_id
and        prices.customer_no = $_SESSION['customer']
order by   prices.product_id asc
  

Как я могу выполнить первый запрос, но если у клиента есть своя цена, то заменить ее на эту? Возможно ли это вообще?

Заранее спасибо.

Стив

Редактировать: Извините, пропустил третью строку в обоих запросах в исходном сообщении.

Комментарии:

1. Итак, это либо прайс-лист клиента, либо стандартный прайс-лист? Или могут быть какие-то цены, зависящие от клиента, а остальные должны быть взяты из стандартного списка?

2. Кстати: Надеюсь, это только в вашем примере вы перекрестно соединяете таблицы. И: Какая у вас версия Oracle? Разве вы не можете использовать явные соединения (ВНУТРЕННЕЕ СОЕДИНЕНИЕ, ПЕРЕКРЕСТНОЕ СОЕДИНЕНИЕ, ЛЕВОЕ СОЕДИНЕНИЕ и т.д.) И должны придерживаться подверженных ошибкам списков таблиц, разделенных запятыми (которые устарели в стандартном SQL уже около двадцати лет)?

Ответ №1:

Вам придется дважды присоединиться к prices таблице, один раз для прейскурантных цен, а затем для указанных цен. Используйте LEFT JOIN для последнего, поскольку у некоторых продуктов не будет указанной цены. Затем используйте NVL для изменения указанной цены по умолчанию на цену по прейскуранту.

 SELECT products.product_id, products.product_desc, NVL(p2.m2, p1.m2)
FROM products
JOIN prices p1 ON p1.product_id = products.product_id
LEFT JOIN prices p2 ON p2.product_id = products.product_id 
                    AND p2.customer_no = $_SESSION['customer']
WHERE p1.customer_no = 0
  

Комментарии:

1. Привет. Спасибо за ответ. Я как-то пропустил WHERE предложение (третью строку) в вопросе. Куда я должен это добавить?

2. Вы имеете в виду prices.product_id = products.product_id ? Я уже добавил это в свой ответ, потому что заметил, что оно отсутствует. Это в ON предложениях.

3. Спасибо. Я продолжаю получать ERROR at line 3: ORA-00933: SQL command not properly ended , но я не вижу, что не так…

4. @user3636943 Имя таблицы не нуждается AS в ключевом слове для псевдонима. (Только Oracle) Просто удалите это!

5. Все еще получаю то же сообщение об ошибке без AS : ERROR at line 3: ORA-00933: SQL command not properly ended .

Ответ №2:

Попробуйте:

 select     prices.product_id, products.product_desc, prices.m2
from       prices, products
where      prices.customer_no = nvl($_SESSION['customer'], 0)
order by   prices.product_id asc
  

Комментарии:

1. По умолчанию это не стандартная цена для продуктов, на которые у клиента нет предложения.

2. Основываясь на SQL операционной системы, customer_no возвращается к 0, если не указан клиент.

3. Клиент всегда указан. Но у них может не быть специальной цены на некоторые продукты, тогда они получают обычную цену, которая поступает от клиента 0.