2017-10-16 63 views
1

我有試圖通過測試的設備。當他們做我得到插入到設備的數據庫,測試,通過或失敗,和時間戳。我想要的是選擇所有通行證並且失敗,但如果通過了,我不想失敗。如果一次測試有多次失敗並且沒有通過,我只想要最近的失敗。SQL根據共享列有條件地選擇一行或兩行

兩個例子。有4行表:

Device Test Pass TimeStamp

X  T1 0 some time 
X  T1 1 some time 

Y  T2 0 some time 
Y  T2 0 some time 

我要選擇當它僅通過X,我不想失敗,因爲它現在已經過去了。對於Y我想要最近的失敗。即使在正確的方向推動,我也會感激。

+0

你到目前爲止嘗試了什麼? – mucio

+0

@mucio一個工會所有自我與where子句,無法引用我的表別名。一堆不起作用的東西。 –

回答

1

這是一個扭曲的優先級查詢可以做到這一點與窗口功能或union all。我們去的第二種方法:

select t.* 
from t 
where t.pass = 1 
union all 
(select top (1) with ties t.* 
from t 
where t.pass = 0 and 
     not exists (select 1 from t t2 where t2.device = t.device and t2.test = t.test and t2.pass = 1) 
order by device, test, row_number() over (order by timestamp desc) 
) 

,或者更簡單的:

select t.* 
from (select t.*, 
      rank() over (partition by by device, test 
          order by pass desc, 
            (case when pass = 0 then timestamp end) desc 
         ) as seqnum 
     from t 
    ) t 
where seqnum = 1; 

rank()的意圖是,所有道將首先與具有秩1的值 - 如果存在。如果沒有,則只有最近的失敗的排名爲1.

+0

所以這是工會所有,是第二個選擇應該別名爲t2?在't2從t選擇1'我得到t是無效的對象。在SQL服務器中。嘗試用交叉連接取代。 –

+0

@ScottClark。 。 。除了'all'拼寫錯誤之外,查詢按照我的意圖書寫。 –

+0

這對我非常有幫助。 rank函數的一個很好的介紹。謝謝。 –

0

聯合使用CTE的所有方法的一種變體,通過單獨的分組和過濾假定合理的數據集大小來提高可讀性。

;with LatestPassingTests as 
(
    select 
     Device, 
     Test, 
     Pass, 
     max([Timestamp]) as 'Timestamp' 
    from t     
    where Pass = 1 
    group by Device, Test, Pass 
), 
DeduplicatedTestResults 
as 
(
    select 
     Device, 
     Test, 
     Pass, 
     [Timestamp] 
    from LatestPassingTests   
    union all 
    select 
     t.Device, 
     t.Test, 
     t.Pass, 
     max(t.[Timestamp]) as 'Timestamp' 
    from @tempstuff as t 
     left outer join LatestPassingTests as p on (t.Device = p.Device) 
    where p.Device is null 
    group by t.Device, t.Test, t.Pass 
) 
select 
    Device, 
    Test, 
    Pass, 
    [Timestamp] 
from DeduplicatedTestResults 
0

如果沒有相同的設備和測試中合格後失敗的可能性,只是使用與最大的時間一個簡單的內部查詢:

select Device, Test, Pass, TimeStamp from table 
join (
select Device, Test, max(Timstamp) as TimeStamp from table group by 1,2) t1 
on t1.Device=table.Device and t1.Test=table.Test and t1.TimeStamp =table.TimeStamp 

如果有內傳球后失敗的可能性相同的設備和測試,你只需要通過,需要2個內部連接:

select Device, Test, Pass, TimeStamp from table join (
select Device, Test, Pass, max(TimeStamp) as TimeStamp from table 
join (
select Device, Test, max(Pass) as Pass from table group by 1,2) t1 
on t1.Device=table.Device and t1.Test=table.Test and t1.Pass =table.Pass 
group by 1,2,3) t2 
on t2.Device=table.Device and t2.Test=table.Test and t2.Pass =table.Pass and t2.TimeStamp =table.TimeStamp 
相關問題