Страницы: 1 2 След.
RSS
Булева сумма или как отобрать одно значение по нескольким совпадающим полям?
 
В запросе получаю таблицу, в которой есть ссылка на документ (например, документ Заказ клиента) и результат выполнения определенных условий (булево). Как из этой таблицы выбрать только те ссылки, по которым выполнены все условия?
 

Простейшее «И» в условии отбора чем не подходит?

ВЫБРАТЬ

              ТЗ.ЗаказКлиента КАК ЗаказКлиента

ИЗ

              ТЗ КАК ТЗ

ГДЕ

              ТЗ.КонтрольноеУсловие1 = ИСТИНА

              И ТЗ.КонтрольноеУсловие2 = ИСТИНА

Или группирование с использованием агрегатной функции «МИНИМУМ»: для тех, где все условия выполнены, будет равно «ИСТИНА», если хотя бы одно не вы полнено – будет «ЛОЖЬ».

ВЫБРАТЬ

              ТЗ.ЗаказКлиента КАК ЗаказКлиента

ИЗ

              ТЗ КАК ТЗ

СГРУППИРОВАТЬ ПО

              ТЗ.ЗаказКлиента

ИМЕЮЩИЕ

              (МИНИМУМ(ТЗ.КонтрольноеУсловие1) = ИСТИНА

                             И МИНИМУМ(ТЗ.КонтрольноеУсловие2) = ИСТИНА)

 
Задача усложнилась тем, что заранее количество контрольных условий не известно, оно может меняться. Поэтому в исходной таблице нет отдельных полей для «КонтрольноеУсловие1», «КонтрольноеУсловие2». Результат проверки находится в одной колонке. Таблица так выглядит:
Изменено: Екатерина - 26.05.2024 01:32:49
 

Т.е., задачу «все ИСТИНА» можно так сформулировать: если в колонке «Результат» есть хотя бы одна «ЛОЖЬ», тогда не выбираем.

Тогда даже проще. Используем агрегатную функцию «МИНИМУМ» только по одной колонке «Результат».

ВЫБРАТЬ

              ТЗ.ЗаказКлиента КАК ЗаказКлиента

ИЗ

              ТЗ КАК ТЗ

СГРУППИРОВАТЬ ПО

              ТЗ.ЗаказКлиента

ИМЕЮЩИЕ

              МИНИМУМ(ТЗ.Результат) = ИСТИНА

Можно пойти через «ЛЕВОЕ СОЕДИНЕНИЕ»: соединяться со значениями «ЛОЖЬ» в колонке «Результат» и отбирать только те строки «Заказов», где такого соединения не будет, т.е. будет выполняться условие «ЕСТЬ NULL». При использовании «СОЕДИНЕНИЯ» возможны дубли строк с одинаковыми ссылками на ЗаказКлиента, поэтому нужно использовать «РАЗЛИЧНЫЕ» и группировку по полю ЗаказКлиента.

ВЫБРАТЬ РАЗЛИЧНЫЕ

              ТЗ.ЗаказКлиента КАК ЗаказКлиента

ИЗ

              ТЗ КАК ТЗ

                             ЛЕВОЕ СОЕДИНЕНИЕ ТЗ КАК ТЗ1

                             ПО ТЗ.ЗаказКлиента = ТЗ1.ЗаказКлиента

                                           И (ТЗ1.Результат = ЛОЖЬ)

ГДЕ

              ТЗ1.ЗаказКлиента ЕСТЬ NULL

 
Есть еще одна трудность. Бывают случаи, что для определенного Заказа какая-то проверка вообще не проводилась. Т.е. какие-то проверки проведены и по ним по всем ИСТИНА, а одна или несколько еще не проведены. Тогда этот запрос включит его в выборку, а его надо исключить.
Вот пример:
- в системе сейчас включены две проверки «1» и «2»
- по заказу 017276 первая проверка успешно выполнена, а второй еще не было, и в таблице нет записи о второй проверке ни положительной, ни отрицательной  нужно считать, что одна из проверок не пройдена и выбрасывать из выборки.
 

Нужно так преобразовать запрос, чтобы отсутствующую запись попала в него со значением ложь. Можно, например, так (покажу с примерами промежуточных результатов).

1)      Прочитали исходные данные во временную таблицу «ТЗ»

ВЫБРАТЬ

              ТЗ.ЗаказКлиента КАК ЗаказКлиента,

              ТЗ.Результат КАК Результат,

              ТЗ.КонтрольноеУсловие КАК КонтрольноеУсловие

ПОМЕСТИТЬ ТЗ

ИЗ

              &тч КАК ТЗ

;

////////////////////////////////////////////////////////////­////////////////////

 

2)      Не знаю, как у вас задаются действующие условия, поэтому в примере полагаю, что включены все, какие есть в исходной таблице à читаю их во временную таблицу «втКонтрольки» (вы можете ее сформировать из своего источника)

ВЫБРАТЬ РАЗЛИЧНЫЕ

              ТЗ.КонтрольноеУсловие КАК КонтрольноеУсловие

ПОМЕСТИТЬ втКонтрольки

ИЗ

              ТЗ КАК ТЗ

;

////////////////////////////////////////////////////////////­////////////////////

Изменено: BIN - 26.05.2024 01:45:40
 

3)      Аналогично получаем список всех заказов «втЗаказы».

ВЫБРАТЬ РАЗЛИЧНЫЕ

              ТЗ.ЗаказКлиента КАК ЗаказКлиента

ПОМЕСТИТЬ втЗаказы

ИЗ

              ТЗ КАК ТЗ

;

Изменено: BIN - 26.05.2024 01:45:56
 

4)     Затем через полное соединение получаем все комбинации Заказ/Условие – «втВсеКомбинации»

////////////////////////////////////////////////////////////­////////////////////

ВЫБРАТЬ

              втЗаказы.ЗаказКлиента КАК ЗаказКлиента,

              втКонтрольки.КонтрольноеУсловие КАК КонтрольноеУсловие

ПОМЕСТИТЬ втВсеКомбинации

ИЗ

              втКонтрольки КАК втКонтрольки,

              втЗаказы КАК втЗаказы

;

////////////////////////////////////////////////////////////­////////////////////

 

5)      Соединяя «все комбинации» с исходной таблицей, получаем «полную таблицу», в которой для каждой комбинации Заказ/Условие определен Результат и если в исходной таблице какой-то комбинации Заказ/Условие не было, то в полной таблице соответствующая ей запись будет иметь значение поля «Результат» = ЛОЖЬ.

ВЫБРАТЬ

              втВсеКомбинации.ЗаказКлиента КАК ЗаказКлиента,

              втВсеКомбинации.КонтрольноеУсловие КАК КонтрольноеУсловие,

              ВЫБОР

                             КОГДА ТЗ.ЗаказКлиента ЕСТЬ NULL

                                           ТОГДА ЛОЖЬ

                             ИНАЧЕ ТЗ.Результат

              КОНЕЦ КАК Результат

ПОМЕСТИТЬ втПолнаяТЗ

             

ИЗ

              втВсеКомбинации КАК втВсеКомбинации

                             ПОЛНОЕ СОЕДИНЕНИЕ ТЗ КАК ТЗ

                             ПО втВсеКомбинации.ЗаказКлиента = ТЗ.ЗаказКлиента И втВсеКомбинации.КонтрольноеУсловие = ТЗ.КонтрольноеУсловие

;

////////////////////////////////////////////////////////////­////////////////////

Изменено: BIN - 26.05.2024 01:46:14
Страницы: 1 2 След.