我有这两张桌子。我想计算最后一个时间段连续发出'1'的con_id的数量。
例如:A1为2,A3为1,但A2和B1为0,因为对于下表的最新结果,它们没有连续“1”。
t_conmast
con_id off_code A1 1 A2 1 B1 2 A3 1
t_readbak
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 :(得分: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 :(得分: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
答案 2 :(得分:1)
如果您的意思是只想在con_id
期间每个 remark
包含1
次,那么您可以执行以下操作:< / p>
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
。
答案 3 :(得分:1)
获取con_id
为0的每个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)
),如果您不信任您的时间戳顺序,请更改比较运算符。