2010-09-01 54 views
1

雖然我知道這不是非常高效,但我需要快速完成這個工作,所以我儘量遵循最簡單的路徑,或者至少我是這麼想的。我試圖從實體中獲取最大數據,並僅考慮USER不爲空的行,並且如果沒有行將USER設置爲null,那麼我會考慮空值。在where子句中使用case表達式

實體的結構如下:

  • ID INT,
  • 的ParentId整型,
  • 的Guid VARCHAR,
  • EventOn日期時間,
  • 用戶INT(空)

所以,查詢是以下一個:

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內的情況。 我能做些什麼來完成我的要求?

+1

什麼是'WHERE'條款旨在實現? '其中RST。[用戶]是(case RST。[用戶]當空,否則不空結束)'即使它是有效的語法,它似乎是多餘的。 – 2010-09-01 15:26:35

+0

從我上面指定的實體中,我只想在字段USER不爲null的行上使用Max(RST.EventOn)。但是,如果所有行都將該字段設置爲空,那麼我將在所有行上都執行Max。這正是我想要做的,當然不正確。 – Hallaghan 2010-09-01 15:28:54

回答

2

我對你在做什麼感到有點困惑。去掉你的文字描述雖然會有如下的幫助?

;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 
+0

不錯。十分優雅。花了我一兩分鐘來弄清楚它是如何工作的,但我喜歡它。 – Bill 2010-09-01 15:57:06

+0

感謝Martin,它的確如我所願。一切正常,謝謝你。 – Hallaghan 2010-09-01 16:25:23

1

我想你只是要在兩個不同的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行在用戶列中都有空值,則此子查詢不會返回一行。

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 
1

這是你的查詢我重新寫:

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