2013-04-29 41 views
-1

我有這兩個表。我想要統計最後一段時間連續註釋'1'的con_id的數量。
例如:2表示A1,1表示A3,而0表示A2和B1,因爲它們對於下表的最新結果連續不具有「1」。通過查詢與內嵌查詢組的SQL幫助

t_conmast

  • CON_ID [PK]
  • off_code
 
con_id off_code 
A1  1 
A2  1 
B1  2 
A3  1 

t_readbak

  • CON_ID [FK]
  • 計數器
  • 備註
  • timestamp [未在表格中顯示;自動由系統插入]
 
con_id counter remark timestamp 
A1  1  0 
A1  3  1 
A1  6  1 
B1  1  1 
B1  2  0 
A2  1  0 
A2  2  1 
A2  3  0 
A3  1  1 

我嘗試和失敗(我加了off_code只是爲了獲得導致單個辦公室)

select con_id, 
     count(con_id) 
from t_readbak 
where remark=1 and timestamp > (select max(timestamp) 
           from t_readbak 
           where remark=0 
           group by con_id) 
and con_id in (select con_id from t_conmast where off_code=1) 

預計輸出

 
con_id count(con_id) 
A1  2 
A2  0 
A3  1 
B1  0 
+0

您可以根據問題中的數據發佈預期的輸出嗎? – 2013-04-29 14:37:43

+0

@EdGibbs編輯:) – Sourav 2013-04-29 14:39:10

+0

你可以(a)描述你如何定義一個「期間」(如在*「我想要計算在最後一個期間持續註釋'1'的con_id的數目」*), (b)闡明辦公室的重要性(大概由'off_code'定義)和(c)將時間戳數據添加到樣本數據集中? – 2013-04-29 14:44:36

回答

1

這是我解決這個問題的方法。首先,計算每個con_id的反向累計和。然後,您第一次在remark = 0處找到一行,請使用該行的值。您可以使用row_number()找到第一個這樣的行。

併發症是當你沒有評論的值爲0.在這種情況下,你只需要總數。

下面的查詢結合這個邏輯到SQL:

select rb.con_id, 
     (case when NumZeros = 0 then numRemarks else cumsum end) as count1 
from (select rb.*, 
      SUM(remark) over (partition by con_id order by counter desc) as cumsum, 
      ROW_NUMBER() over (partition by con_id, remark order by counter desc) as remark_counter, 
      SUM(case when remark = 0 then 1 else 0 end) as NumZeros, 
      SUM(remark) over (partition by con_id) as numRemarks 
     from t_readbak rb 
    ) rb 
where (remark_counter = 1 and remark = 0) or 
     (NumZeros = 0 and remark_counter = 1) 
1

左自聯接可能會奏效。事情是這樣的:

select con_id, count(*) records 
from t_readback t1 left join t_readback t2 using (con_id, remark) 
where remark = 1 
and t1.counter < t2.counter 
group by con_id 
1

如果你的意思,你只希望包括con_id計數如果remark在週期爲1,你可以做這樣的事情:

SELECT 
    con_id, 
    COUNT(CASE remark = 1 THEN 1 END) AS Remark1Count, 
    COUNT(CASE remark <> 1 THEN 1 END) AS RemarkNot1Count 
FROM t_conmast 
INNER JOIN t_readbak ON t_conmast.con_id = t_readbak.con_id 
WHERE your-timestamp-condition 
GROUP BY con_id 
HAVING COUNT(CASE remark <> 1 THEN 1 END) = 0 

HAVING將篩選出具有remark <> 1的任何con_id

1

獲得每個con_id的最大時間戳,其中remark爲0. 此後再次針對每個con_id計數具有較小時間戳的項目。remark設置爲1在這些記錄中的建設:

select con_id 
     , count(*) 
     from t_readbak master 
inner join t_conmast office on ( office.off_code = 1 
           and office.con_id = master.con_id) 
inner join (
       select con_id   con_id 
        , max(timestamp) ts 
        from (
          select con_id 
           , remark 
           , timestamp 
           from t_readbak 
          where remark = 0 
         ) noremark 
       group by con_id 
      ) cutoff 
     on (master.con_id = cutoff.con_id) 
     where master.timestamp > cutoff.ts 
    group by master.con_id 
      ; 

countermin(counter)timestampmax(timestamp))更換和改變比較運算,如果你不能信任你的時間戳排序。