Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Подставить значения "по умолчанию" в результат запроса  (Прочитано 9866 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Kivals
Команда клуба

ca
Offline Offline
Пол: Мужской

WWW
« : 15-08-2011 14:22 » 

Имеем некую абстрактную СУБД, работающую по стандарту SQL-92 (на самом деле нужно для 1С, но в рамках этой задачи аналогия правомерна).

Исходные данные:
Таблица Номенклатура (goods):
Наименование (description)
Бренд (id_brand)
Пол (sex)

Таблица Реализаторы (sellers)
Реализатор (id_seller) NOT NULL
Бренд (id_brand)
Пол (sex)

На выходе нужно получить таблицу Реализаторы номенклатуры:
Наименование (description)
Бренд (id_brand)
Пол (sex)
Реализатор (id_seller)

сформированную по следующим правилам:
1. Если в таблице реализаторы есть полное соответствие параметров (бренд, пол) - берем это значение
2. Иначе если есть соответствие только бренда и значение sellers.sex IS NULL - берем это значение
3. Иначе подставляем значение по умолчанию (sellers.id_brand IS NULL & sellers.sex IS NULL)

Вот пример:


Результат нужно получить запросом (или набором запросов с временными таблицами) без использования функций

Добавлено через 11 минут и 48 секунд:
Доп.условие (не обязательно): желательно сделать запрос, который нужно минимально редактировать когда количество полей для связи увеличится (например 3 а не 2 - добавим еще Цвет).
При этом считаем что есть четкая логика приоритетов по порядку полей: Бренд, Пол, Цвет.
Приоритет 1: Бренд, Пол, Цвет
Приоритет 2: Бренд, Пол, NULL
Приоритет 3: Бренд, NULL, NULL
Приоритет 4: NULL, NULL, NULL
Значения NULL возможны только справа подряд, т.е. варианты Бренд, NULL, Цвет или NULL, Пол, NULL недопустимы (контролируется триггерами)


* sc-20110815171839.png (14.37 Кб - загружено 1454 раз.)
« Последнее редактирование: 15-08-2011 14:34 от Kivals » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 15-08-2011 14:45 » 

Вроде так:

Код: (SQL)
SELECT DISTINCT
  Goods.description,
  Goods.id_brand,
  Goods.sex,
  COALESCE(Sellers_Defined.id_seller, Sellers_PartlyDefined.id_sellers, Sellers_Default.id_seller) AS id_seller
FROM
  Goods
    LEFT OUTER JOIN Sellers AS Sellers_Defined ON Goods.id_brand = Sellers_Defined.id_brand AND Goods.sex = Sellers_Defined.sex
    LEFT OUTER JOIN Sellers AS Sellers_PartlyDefined ON Goods.id_brand = Sellers_PartlyDefined.id_brand AND Sellers_PartlyDefined.sex IS NULL
    LEFT OUTER JOIN Sellers AS Sellers_Default ON Sellers_Defаult.id_brand IS NULL AND Sellers_Default.sex IS NULL
Но если "Васечкиных" будет несколько, то номенклатурная позиция будет повторяться для каждого "Васечкина".

Думаю, что как это расширять на несколько параметров стравнения - очевидно.
« Последнее редактирование: 15-08-2011 15:03 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Kivals
Команда клуба

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 15-08-2011 15:05 » 

Идея понятна, только и для 2х полей нужен еще один left join:
Код: (SQL)
LEFT OUTER JOIN Sellers AS Sellers_ByBrand ON Goods.id_brand = Sellers_ByBrand.id_brand AND Sellers_ByBrand.sex IS NULL
ну и соответственно тогда в шапке:
Код: (SQL)
COALESCE(COALESCE(Sellers_Defined.id_seller, Sellers_ByBrand.id_seller), Sellers_Default.id_seller) AS id_seller

К сожалению расширение на 3 поля будет очевидным, но неудобным: добавлять условия нужно будет в каждый join Жаль
А возможено ли такое решение, чтобы добавление еще одного поля связи решалось только добавлением нового блока, не трогая весь остальной запрос?

Добавлено через 2 минуты и 28 секунд:
Я думал над вариантом чтобы первым запросом выбрать все возможные варианты, отсортировав их по приоритету, а вторым запросом объединить с максимальным приоритетом из результатов первого запроса.
Или же по-моему это должно получится и через вложенный запрос (не знаю как в SQL-92, но для меня это допустимо)

Добавлено через 1 минуту и 30 секунд:
Но если "Васечкиных" будет несколько, то номенклатурная позиция будет повторяться для каждого "Васечкина".
Это понятно - предполагаем что за однозначностью условий следит система и накладок быть не должно.
« Последнее редактирование: 15-08-2011 15:09 от Kivals » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 15-08-2011 15:10 » 

Kivals, но ещё ведь важен порядок этих JOIN, который совпадает с порядком полей в COALESCE.

Можно попробовать написать динамический запрос, которому в качестве аргументов передаются поля в порядке возрастания/убывания значимости для результата. Но способ его исполнения уже не будет стандартным.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Kivals
Команда клуба

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 15-08-2011 15:24 » new

Dimka, да, спасибо - мысль с динамическим запросом заслуживает внимания, хотя сейчас в моей конкрентой ситуации и неприемлема.
Рабочий ответ получил, спасибо! Но если у кого будет желание придумать что-то "покрасивше" - вопрос считаем открытым Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines