Фильтрация сложного SQL-запроса - PullRequest
0 голосов
/ 24 января 2012

Единица измерения - hmy, scode, hProperty

InsurancePolicy - hmy, hUnit, dtEffective, sStatus

Select MAX(i2.dtEffective) as maxdate, u.hMy, MAX(i2.hmy) as InsuranceId, 
    i2.sStatus 
from unit u 
    left join InsurancePolicy i2 on i2.hUnit = u.hMy 
        and i2.sStatus in ('Active', 'Cancelled', 'Expired')  
where u.hProperty = 2
Group By u.hmy, i2.sStatus
order by u.hmy

Этот запрос вернет значения для страхового полиса с последней датой вступления в силу (Max(dtEffective)). Я добавил Max(i2.hmy), поэтому, если на последнюю дату вступления в силу было более одного страхового полиса, он вернет в базу данных тот, у кого самый высокий идентификатор (i2.hmy).

Предположим, что было подразделение, к которому были прикреплены 3 страховых полиса с одной и той же последней датой вступления в силу, и у всех был разный статус sStatus '. Результат будет выглядеть так:

maxdate    UnitID    InsuranceID    sStatus
1/23/12    2949      1938           'Active'
1/23/12    2949      2343           'Cancelled'
1/23/12    2949      4323           'Expired'

Как отфильтровать результаты, чтобы при наличии нескольких страховых полисов с различным статусом для одной и той же единицы и на одну и ту же дату сначала мы выбирали страховой полис со статусом 'Active', если его не существует, выберите 'Cancelled', а если этого не существует, выберите 'Expired'.

Ответы [ 2 ]

0 голосов
/ 26 января 2012

Вы можете сделать это с помощью одного оператора SQL, но он будет почти нечитаем для вашего обычного разработчика t-sql.Я бы предложил разбить этот запрос на несколько шагов.

Во-первых, я объявил бы переменную таблицы и поместил бы все записи, которые не требуют манипуляций, в эту таблицу (т. Е. Единицы, которые не имеют нескольких статусов на одну и ту же дату = хорошие записи).

Затем получите список ваших записей, над которыми нужно поработать (несколько статусов в одну и ту же дату для одного и того же UnitID) и поместите их в переменную таблицы.Я бы создал столбец «ранг» в этой табличной переменной, используя оператор регистра, как показано здесь:

Псевдокод: КОГДА АКТИВЕН, ТОГДА ЕЩЕ, КОГДА ОТМЕНЕН, ТО 2, ЕЩЕ, КОГДА истек, ТО, 3, КОНЕЦ

Затем удалите записи, где 2 и 3 существуют с 1 Затем удалите записи, где 2 и 3

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

Легко поддаться попыткам сделать слишком много в одном операторе SQL.Разбейте задачи, чтобы вам было легче развиваться и быть более управляемыми в будущем.Если вам придется редактировать этот SQL через несколько лет, вы будете благодарить себя, не говоря уже о других разработчиках, которым, возможно, придется принять ваш код.

0 голосов
/ 24 января 2012

Кажется, это вопрос правильного ранжирования строк InsurancePolicy и последующего присоединения Unit к набору строк с самым высоким рейтингом первого:

;
WITH ranked AS (
  SELECT
    *,
    rnk = ROW_NUMBER() OVER (
      PARTITION BY hUnit
      ORDER BY dtEffective DESC, sStatus, hmy DESC
    )
  FROM InsurancePolicy
)
SELECT
  i2.dtEffective AS maxdate,
  u.hMy,
  i2.hmy AS InsuranceId,
  i2.sStatus
FROM Unit u
  LEFT JOIN ranked i2 ON i2.hUnit = u.hMy AND i2.rnk = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...