(SQLite) 计算一个值连续重复 3 次的次数

Posted

技术标签:

【中文标题】(SQLite) 计算一个值连续重复 3 次的次数【英文标题】:(SQLite) Count number of times a value repeats 3 times continuously 【发布时间】:2019-06-25 11:40:09 【问题描述】:

我知道这是一个复杂的查询,因此我为此设置了一个单独的列,但是该列包含几乎 99% 的值为 null(这非常低效),因此我想知道它可以通过一个查询。

我有这样的表:

TransactionId | Value | ProductId
      1           3         2
      2           2         2           
      3           1         2
      4           0         4
      5           0         4
      6           0         4
      7           3         7
      8           3         7
      9           1         7
     10           0         3
     11           0         3
     12           0         3
     13           5         1
     14           2         1
     15           3         1
     16           0         4
     17           0         4
     18           0         4

现在的查询是,如果对于3个连续产品id,对应的值为0(按照TransactionId ASC的顺序),那么ProductId会被计为1,即 p>

ProductId | Count 
    4         2
    3         1

我们如何查询这个?

一个可选的简短问题:p

如果我的列大部分为空值,可以吗?

【问题讨论】:

如果有四个相邻的行都是 0,会发生什么?七? 永远不会出现value列有4个相邻的0且对应的productid相同的情况 发布包含空值的样本数据,并解释在 productid 为 0,null,0,0,null 的情况下会发生什么。还有consecutive product ids,你的意思是按TransactionId连续排序,对吧? 是的consective product idsTransactionid 订购。此外,在我的数据库中,null 和 0 的含义相同。因此,即使对于 productid 连续为 0, null, 0 ,对于相应的 productid 也应计为 1 【参考方案1】:

在较新版本的 SQLite 中,可以使用lag()/lead()

select product_id, count(*)
from (select t.*,
             (case when value = 0 and
                        lead(value, 1) over (partition by productid order by transactionid) = 0 and
                        lead(value, 2) over (partition by productid order by transactionid) = 0
                   then 1
              end) as three_zero_flag
      from t
     ) t
where three_zero_flag = 1
group by product_id

【讨论】:

如果你不介意,你能解释一下滞后/领先在这里是如何工作的吗? Lag() function... docs.microsoft.com/en-us/sql/t-sql/functions/… Lead() function... docs.microsoft.com/en-us/sql/t-sql/functions/… 将滞后视为落后。因此对于当前行,lag() 将查看前一行,lead() 将查看下一个后续(前面)行。 也许更好地查看 SQLite 文档 sqlite.org/windowfunctions.html#built_in_window_functions 而不是 Microsoft SQL Server 非常感谢您在这里帮助我! :) 我认为这会很好。当我回到家时,我会检查它是否在我的主数据库上工作正常并接受答案。【参考方案2】:

首先使用 CTE 获取具有 3 个连续 0 的行,然后在表中仅包含 1 个(因此只会计算 1 个):

with 
cte as (
  select * from (
    select *,
      lag(transactionid) over (order by transactionid) previd,
      lead(transactionid) over (order by transactionid) nextid,
      lag(productid) over (order by transactionid) prevprodid,
      lead(productid) over (order by transactionid) nextprodid,
      lag(value) over (order by transactionid) prevvalue,
      lead(value) over (order by transactionid) nextvalue
    from tablename
  ) t
  where 
    productid = prevprodid and productid = nextprodid and 
    coalesce(value, 0) = 0 and  coalesce(prevvalue, 0) = 0 and coalesce(nextvalue, 0) = 0
),
triples as (select previd id from cte union all select nextid from cte)

select productid, count(*) counter 
from tablename 
where transactionid not in (select id from triples)
group by productid

请参阅demo。 结果:

| ProductId | counter |
| --------- | ------- |
| 1         | 3       |
| 2         | 3       |
| 3         | 1       |
| 4         | 2       |
| 7         | 3       |

【讨论】:

以上是关于(SQLite) 计算一个值连续重复 3 次的次数的主要内容,如果未能解决你的问题,请参考以下文章

二十:数字重复长度计算

用SQL计算同一个字符(汉字、字母、数字、表情、符号)连续重复出现的次数

如何计算bash中一列数据中的连续重复次数?

计算一个值在 Hive/SQL 中连续出现的次数

SQL:连续天数的计算方法

MySQL连续出现的数字