Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Исключение из результатов запроса записей с меньшим значением поля  [new]
Oomel
Member

Откуда:
Сообщений: 23
Здравствуйте, товарищи!

Имеется вот такой запрос:
SELECT
  1                           AS "TYPE",
  F$SUMOB                     AS SNDE,
  T$OBOROT.F$UID,
  T$MAPPINGS.F$UID,
  T$OBOROT.F$SCHETO,
  T$OBOROT.F$SUBOSSCH,
  MAPPINGS.F$SCHETO,
  MAPPINGS.F$SUBOSSCH,
 (CASE WHEN COALESCE(MAPPINGS.F$SCHETO  ,'') = '' THEN 0 ELSE 1 END +
  CASE WHEN COALESCE(MAPPINGS.F$SUBOSSCH,'') = '' THEN 0 ELSE 1 END +
  CASE WHEN COALESCE(MAPPINGS.F$SCHETK  ,'') = '' THEN 0 ELSE 1 END +
  CASE WHEN COALESCE(MAPPINGS.F$SUBSCHK ,'') = '' THEN 0 ELSE 1 END ) /4.0*100 AS OCCUPANCY,
  FROM (SELECT F$UID FROM T$OBOROT WHERE (T$OBOROT.F$DATE BETWEEN '2017-01-01' AND '2017-31-03')) AS OBOROT INNER
  T$OBOROT ON T$OBOROT.F$UID  = OBOROT.F$UID LEFT JOIN
 (
  SELECT
    F$UID,
    F$SCHETO  , F$SCHETK  ,
    F$SUBOSSCH, F$SUBSCHK ,
  FROM T$MAPPINGS
  WHERE T$MAPPINGS.F$TYPE = 1
 ) AS MAPPINGS ON MAPPINGS.F$SCHETO   = CASE WHEN MAPPINGS.F$SCHETO   = '' THEN '' ELSE T$OBOROT.F$SCHETO   END AND
                  MAPPINGS.F$SUBOSSCH = CASE WHEN MAPPINGS.F$SUBOSSCH = '' THEN '' ELSE T$OBOROT.F$SUBOSSCH END AND
                  MAPPINGS.F$SCHETK   = CASE WHEN MAPPINGS.F$SCHETK   = '' THEN '' ELSE T$OBOROT.F$SCHETK   END AND
                  MAPPINGS.F$SUBSCHK  = CASE WHEN MAPPINGS.F$SUBSCHK  = '' THEN '' ELSE T$OBOROT.F$SUBSCHK  END


Всего имеются два вопроса:
1. Обратите внимание на соединение синонима MAPPINGS с таблицей T$OBOROT.
Таблица MAPPINGS содержит в себе некие правила по которым выгружаются данные из таблицы T$OBOROT, содержащей бухгалтерские данные.
В таблице T$OBOROT поля F$SCHETO, F$SUBOSSCH, F$SCHETK, F$SUBSCHK not null.
В таблице MAPPINGS аналогичные поля могут содержать значение '', которое говорит о том, что для данного поля подходит любое значение из соответствующего поля в T$OBOROT.
Есть ли какой-нибудь способ организовать соединение таблиц по следующей логике: Если в таблице MAPPINGS поле пустое, тогда любое значение из T$OBOROT, иначе точное соответствие.
2. Если использовать вышеописанный вариант запроса, тогда возникает следующая ситуация: в таблице T$OBOROT есть запись со значениями полей F$SCHETO = '1' и F$SUBOSSCH = '2', в таблице MAPPINGS присутствуют два правила в первом значения полей F$SCHETO = '1' и F$SUBOSSCH = '', а во втором аналогичны записи из T$OBOROT.
При выполнении запроса в результат попадут две строки:
SNDEOCCUPANCYT$OBOROT.F$SCHETOT$OBOROT.F$SUBOSSCHMAPPINGS.F$SCHETOMAPPINGS.F$SUBOSSCHT$OBOROT.F$UIDMAPPINGS.F$UID
1096.5025121''11
1096.5050121212

Необходимо в запросе исключать строки с меньшим значением Occupancy и равным значением T$OBOROT.F$UID.
Как это лучше всего сделать?
19 апр 17, 08:10    [20413054]     Ответить | Цитировать Сообщить модератору
 Re: Исключение из результатов запроса записей с меньшим значением поля  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31442
Oomel
Как это лучше всего сделать?
Нужно заменить LEFT JOIN на OUTER APPLY, внутри которого будет TOP 1
19 апр 17, 10:18    [20413391]     Ответить | Цитировать Сообщить модератору
 Re: Исключение из результатов запроса записей с меньшим значением поля  [new]
Oomel
Member

Откуда:
Сообщений: 23
alexeyvg
Oomel
Как это лучше всего сделать?
Нужно заменить LEFT JOIN на OUTER APPLY, внутри которого будет TOP 1

К сожалению, нет возможности использовать OUTER APPLY. Запрос, перед отправкой на сервер, компилируется сторонней программой, которая не переваривает некоторые плюшки, и все варианты APPLY в их числе.
19 апр 17, 10:50    [20413511]     Ответить | Цитировать Сообщить модератору
 Re: Исключение из результатов запроса записей с меньшим значением поля  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
Oomel
Запрос, перед отправкой на сервер, компилируется сторонней программой, которая не переваривает некоторые плюшки, и все варианты APPLY в их числе.
Сделайте представление, которое скроет непереваримые фичи от это программы.
19 апр 17, 11:05    [20413559]     Ответить | Цитировать Сообщить модератору
 Re: Исключение из результатов запроса записей с меньшим значением поля  [new]
Oomel
Member

Откуда:
Сообщений: 23
invm
Сделайте представление, которое скроет непереваримые фичи от это программы.

Увы у программы и тут вкрались ограничения. Из всех объектов базы данных MSSQL для программы видны только таблицы и хранимые процедуры и не будет возможности обратиться к представлению.
Можно только запросом создать временное представление, но в запросе этого представления, как вы уже думаю догадались, не будет возможности использовать APPLY :D
19 апр 17, 11:39    [20413702]     Ответить | Цитировать Сообщить модератору
 Re: Исключение из результатов запроса записей с меньшим значением поля  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
Если у вас там все такое капризное сделайте "в лоб":
if object_id('tempdb..#t', 'U') is not null
 drop table #t;

SELECT
  1                           AS "TYPE",
  F$SUMOB                     AS SNDE,
  T$OBOROT.F$UID,
  T$MAPPINGS.F$UID,
  T$OBOROT.F$SCHETO,
  T$OBOROT.F$SUBOSSCH,
  MAPPINGS.F$SCHETO,
  MAPPINGS.F$SUBOSSCH,
 (CASE WHEN COALESCE(MAPPINGS.F$SCHETO  ,'') = '' THEN 0 ELSE 1 END +
  CASE WHEN COALESCE(MAPPINGS.F$SUBOSSCH,'') = '' THEN 0 ELSE 1 END +
  CASE WHEN COALESCE(MAPPINGS.F$SCHETK  ,'') = '' THEN 0 ELSE 1 END +
  CASE WHEN COALESCE(MAPPINGS.F$SUBSCHK ,'') = '' THEN 0 ELSE 1 END ) /4.0*100 AS OCCUPANCY
into
 #t
  FROM (SELECT F$UID FROM T$OBOROT WHERE (T$OBOROT.F$DATE BETWEEN '2017-01-01' AND '2017-31-03')) AS OBOROT INNER
  T$OBOROT ON T$OBOROT.F$UID  = OBOROT.F$UID LEFT JOIN
 (
  SELECT
    F$UID,
    F$SCHETO  , F$SCHETK  ,
    F$SUBOSSCH, F$SUBSCHK ,
  FROM T$MAPPINGS
  WHERE T$MAPPINGS.F$TYPE = 1
 ) AS MAPPINGS ON MAPPINGS.F$SCHETO   = CASE WHEN MAPPINGS.F$SCHETO   = '' THEN '' ELSE T$OBOROT.F$SCHETO   END AND
                  MAPPINGS.F$SUBOSSCH = CASE WHEN MAPPINGS.F$SUBOSSCH = '' THEN '' ELSE T$OBOROT.F$SUBOSSCH END AND
                  MAPPINGS.F$SCHETK   = CASE WHEN MAPPINGS.F$SCHETK   = '' THEN '' ELSE T$OBOROT.F$SCHETK   END AND
                  MAPPINGS.F$SUBSCHK  = CASE WHEN MAPPINGS.F$SUBSCHK  = '' THEN '' ELSE T$OBOROT.F$SUBSCHK  END;

select
 a.*
from
 #t a
where
 not exists(select * from #t where F$UID = a.F$UID and OCCUPANCY > a.OCCUPANCY);

Или реализуйте через хранимую процедуру.
19 апр 17, 12:08    [20413830]     Ответить | Цитировать Сообщить модератору
 Re: Исключение из результатов запроса записей с меньшим значением поля  [new]
Oomel
Member

Откуда:
Сообщений: 23
invm,

О, а вот это уже идея. От чего-то загнать всю выборку во временную таблицу я не подумал...
Благодарствую, буду пробовать.
19 апр 17, 12:20    [20413892]     Ответить | Цитировать Сообщить модератору
 Re: Исключение из результатов запроса записей с меньшим значением поля  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31442
Oomel
К сожалению, нет возможности использовать OUTER APPLY.
Если в таблице T$MAPPINGS есть ПК, то можно получить ИД записи в подзапросе с TOP 1, а потом сделать LEFT JOIN с этим полученным ИД.

Но вообще проблемы такого умного софта должны решать разработчики, или убрать багу с невозможностью использования APPLY
20 апр 17, 13:44    [20418656]     Ответить | Цитировать Сообщить модератору
 Re: Исключение из результатов запроса записей с меньшим значением поля  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31442
alexeyvg
Oomel
К сожалению, нет возможности использовать OUTER APPLY.
Если в таблице T$MAPPINGS есть ПК, то можно получить ИД записи в подзапросе с TOP 1, а потом сделать LEFT JOIN с этим полученным ИД.
Ещё можно пронумеровать записи с группировкой, и выбрать с №1
Хотя не знаю, "пропустит" ли это ваша программа :-)
В общем, тут куча способов, и чем меньше фичей сиквела "пропускает" программа, тем они медленнее.
20 апр 17, 13:46    [20418667]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить