根据前一行值创建条件 ROW_NUMBER() 分区子句

我的账户名

我有一张看起来像这样的表:

+----------------+--------+
| EvidenceNumber | ID     |
+----------------+--------+
| 001            |      8 |
| 001.A          |      8 |
| 001.A.01       |      8 |
| 001.A.02       |      8 |
| 001.B          |      8 |
| 001.C          |      8 |
| 001.D          |      8 |
| 001.E          |      8 |
| 001.F          |      8 |
| 001.G          |      8 |
| 001.G.01       |      8 |
+----------------+--------+

如果 001 是一个包,它的内部是 001.A、001.B,依此类推到 001.G

在上面的输出中,001.A 是另一个包,该包包含 001.A.01 和 001.A.02。同样的事情可以用 001.G.01 看到。

此表中的每个条目要么是一个包,要么是一个项目。我只对计算每个 ID 的项目数量感兴趣。

由于 001.A.01 和 001.A.02 是我们最后看到的“001.A”,我们知道 A.01 和 A.02 是项目。

因为我们只看到 001.B 一次,那也是一个项目。

001.G 是包,而 001.G.01 是物品。

上面的输出显示了 8 个项目和 3 个包。

我觉得 Row_number 和 Partition 子句是完成这项工作的完美工具,但我找不到基于使用前一行值的子句进行分区的方法。

也许这样的事情在这里甚至没有必要,但我把它想象成:

{001} -- 变量 {001}.A -- 又见变量,显然 001 是一个包。创建新变量 {001.A} 并继续。

{001.A}.01——同样的事情。{001.A.01} - 唯一变量。这是最后一步。这是一个包,应该是第 1 行。

显然,下面的代码只是将每个项目的“ItemNum”设为 1,因为没有重复项。

SELECT 
ROW_NUMBER() OVER(Partition BY EvidenceNumber ORDER BY EvidenceNumber) AS ItemNum,
EvidenceNumber, 
ID
FROM EVIDENCE
WHERE ID = '18'
ORDER BY EvidenceNumber
+---------+----------------+--------+
| ItemNum | EvidenceNumber | ID     |
+---------+----------------+--------+
|       1 | 001            |      8 |
|       1 | 001.A          |      8 |
|       1 | 001.A.01       |      8 |
|       1 | 001.A.02       |      8 |
|       1 | 001.B          |      8 |
|       1 | 001.C          |      8 |
|       1 | 001.D          |      8 |
|       1 | 001.E          |      8 |
|       1 | 001.F          |      8 |
|       1 | 001.G          |      8 |
|       1 | 001.G.01       |      8 |
+---------+----------------+--------+

理想情况下,它只会对项目进行分区,因此在这种情况下:

+---------+----------------+----+
| ItemNum | EvidenceNumber | ID |
+---------+----------------+----+
|       0 | 001            |  8 |
|       0 | 001.A          |  8 |
|       1 | 001.A.01       |  8 |
|       2 | 001.A.02       |  8 |
|       3 | 001.B          |  8 |
|       4 | 001.C          |  8 |
|       5 | 001.D          |  8 |
|       6 | 001.E          |  8 |
|       7 | 001.F          |  8 |
|       0 | 001.G          |  8 |
|       8 | 001.G.01       |  8 |
+---------+----------------+----+
戈登·利诺夫

我不认为单独的窗口函数是最好的方法。反而:

select t.*,
       (case when exists (select 1
                          from evidence t2
                          where t2.caseid = t.caseid and
                                t2.EvidenceNumber like t.EvidenceNumber + '.%'
                         )
             then 0 else 1
        end) as is_item
from evidence t ;

然后使用另一个子查询总结这些:

select t.*,
       sum(is_item) over (partition by caseid order by EvidenceNumber) as item_counter
from (select t.*,
             (case when exists (select 1
                                from evidence t2
                                where t2.caseid = t.caseid and
                                      t2.EvidenceNumber like t.EvidenceNumber + '.%'
                               )
                   then 0 else 1
              end) as is_item
      from evidence t
     ) t;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章