-1

我有这两张桌子。我想计算最后一个时期连续带有“1”的 con_id 的数量。
例如:A1 为 2,A3 为 1,但 A2 和 B1 为 0,因为对于下表的最新结果,它们没有连续的“1”。

t_conmast

  • con_id [pk]
  • 关闭代码
  
con_id off_code
A1 1
A2 1
B1 2
A3 1

t_readbak

  • con_id [fk]
  • 柜台
  • 评论
  • 时间戳[未在表中显示;系统自动插入]
con_id 计数器备注时间戳
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 计数(con_id)
A1 2
A2 0
A3 1
B1 0
4

4 回答 4

1

这是我解决这个问题的方法。首先,计算每个con_id. 然后,第一次点击 where 行时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)
于 2013-04-29T14:45:04.357 回答
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
于 2013-04-29T14:45:51.653 回答
1

如果您的意思是您只想在期间的每个con_id为 时包含计数,您可以执行以下操作: remark1

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过滤掉任何con_id具有remark <> 1.

于 2013-04-29T14:50:07.290 回答
1

获取每个为 0 的最大时间戳。con_id此后remark,再次为每个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
          ;

如果您不能信任您的时间戳排序,请将timestamp( max(timestamp))替换为counter( min(counter)) 并更改比较运算符。

于 2013-04-29T15:16:50.823 回答