2013-04-29 48 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))更换和改变比较运算,如果你不能信任你的时间戳排序。