Использование выражения case в предложении where - PullRequest
1 голос
/ 01 сентября 2010

Хотя я знаю, что это не очень эффективно, мне нужно, чтобы это работало быстро, поэтому я стараюсь идти по самому простому пути, или, по крайней мере, я так думал.Я пытаюсь извлечь максимальные данные из сущности и принять во внимание только те строки, в которых USER не равен NULL, и в случае, если ни в одной строке для USER не задано значение NULL, тогда я буду принимать во внимание нулевые значения.

Структура сущности следующая:

  • Id int,
  • ParentId int,
  • Guid varchar,
  • EventOn DateTime,
  • User int (null)

Итак, запрос следующий:

select RS.[$Id] RangeSheet,
       GRST.EventOn,
       RSIS.Id [Status],
       RSIS.Name StatusRefex    
  from RangeSheet RS
left outer join (select RST.ParentId RangeSheet,
                        MAX(RST.EventOn) EventOn
                   from RangeSheetTime RST
                  where RST.[User] is (case RST.[User] when null then null else not null)
               group by RST.ParentId) GRST on RS.[$Id]=GRST.RangeSheet
left outer join RangeSheetTime RST on GRST.EventOn=RST.EventOn 
                                  and GRST.RangeSheet=RST.ParentId
left outer join RangeSheetItemState RSIS on (case when RST.StartOrEnd = 1 then 1 when RST.StartOrEnd = 0 then 4 else null end) = RSIS.Id
 where RS.[$IsDeleted]=0

Случай, с которым у меня возникли проблемы, - это случай изнутривид GRST.Что я могу сделать, чтобы выполнить мои требования?

Ответы [ 3 ]

2 голосов
/ 01 сентября 2010

Я немного озадачен тем, что ты делаешь.Отключение вашего текстового описания, хотя бы что-то вроде следующей помощи?

;WITH t AS
     ( SELECT  Id     ,
              ParentId,
              Guid    ,
              EventOn ,
              USER    ,
              RANK() OVER (PARTITION BY ParentId ORDER BY
              CASE
                       WHEN USER IS NULL
                       THEN 0
                       ELSE 1
              END DESC, EventOn DESC) Rnk
     )
SELECT *
FROM   t
WHERE  Rnk=1
1 голос
/ 01 сентября 2010

Вот мой переписать ваш запрос:

   SELECT rs.[$Id] RangeSheet,
          grst.eventon,
          rsis.id AS [Status],
          rsis.name AS StatusRefex    
     FROM RANGESHEET rs
LEFT JOIN (SELECT rst.ParentId,
                  rst.EventOn,
                  RANK() OVER (PARTITION BY rst.parentid
                                   ORDER BY CASE
                                              WHEN rst.user IS NULL THEN 0
                                              ELSE 1
                                            END DESC, rst.eventon DESC) Rnk
            FROM RANGESHEETTIME rst) grst ON grst.parentid = rs.[$Id] 
                                         AND grst.rnk = 1
LEFT JOIN (SELECT rst.eventon,
                  rst.parentid,
                  CASE rst.startorend
                    WHEN 0 THEN 4
                    WHEN 1 THEN 1
                    ELSE NULL
                  END AS item_state_id
             FROM RANGESHEETTIME rst
            WHERE rst.startorend IN (0, 1)) x ON x.eventon = GRST.EventOn
                                             AND x.parentid = GRST.RangeSheet
LEFT JOIN RANGESHEETITEMSTATE rsis ON rsis.id = x.item_state_id
1 голос
/ 01 сентября 2010

Я думаю, что вам просто нужно соединиться слева в двух разных подзапросах Max.

    left join (
    select RST.ParentId RangeSheet,
           MAX(RST.EventOn) EventOn
    from RangeSheetTime RST
    where Not RST.[User] is NULL
    group by RST.ParentId) max1

Этот подзапрос не будет возвращать строку, если все столбцы ParentID имеют нули в столбце User.1004 *

и

left join (
select RST.ParentId RangeSheet,
       MAX(RST.EventOn) EventOn
from RangeSheetTime RST
group by RST.ParentId) max2

Теперь просто выберите нужное значение.

coalesce(max1.EventOn, max2.EventOn) as EventOn
...