查询以计算特定列值的出现次数

问题描述 投票:0回答:3

假设我有一个具有以下值的表

1
1
1
2
2
2
3
3
3
1
1
1
2
2
2

我需要像这样得到一个输出,它计算每个特定值的出现次数

 1  1
 1  2
 1  3
 2  1
 2  2
 2  3
 3  1
 3  2 
 3  3
 1  1
 1  2
 1  3
 2  1
 2  2
 2  3

注意:这是一个示例表实际表是一个包含大量行和列的复杂表,查询包含更多条件

sql postgresql
3个回答
2
投票

如果数字在不同的“岛屿”上重复,那么您需要计算一个值以保持这些岛屿的首位(grpnum)。第一步可以通过从分区行号中减去原始的从上到下的行号(raw_rownum)来进行。该结果为每个“岛”提供了该岛独有的参考,然后可用于对随后的行号进行分区。由于每个订单都会影响结果,我发现有必要使用单独的步骤并通过先前的计算,以便可以重复使用。

SQL Fiddle

MS SQL Server 2014架构设置:

CREATE TABLE Table1  ([num] int);

INSERT INTO Table1  ([num])
VALUES  (1),(1),(1),(2),(2),(2),(3),(3),(3),(1),(1),(1),(2),(2),(2);

查询1:

select
    num
    , row_number() over(partition by (grpnum + num) order by raw_rownum) rn
    , grpnum + num island_num
from (
    select
           num
         , raw_rownum - row_number() over(partition by num order by raw_rownum) grpnum
         , raw_rownum
    from (
          select
              num
             , row_number() over(order by (select null)) as raw_rownum
          from table1
         ) r
     ) d
;

Results

| num | rn | island_num |
|-----|----|------------|
|   1 |  1 |          1 |
|   1 |  2 |          1 |
|   1 |  3 |          1 |
|   2 |  1 |          5 |
|   2 |  2 |          5 |
|   2 |  3 |          5 |
|   1 |  1 |          7 |
|   1 |  2 |          7 |
|   1 |  3 |          7 |
|   3 |  1 |          9 |
|   3 |  2 |          9 |
|   3 |  3 |          9 |
|   2 |  1 |         11 |
|   2 |  2 |         11 |
|   2 |  3 |         11 |

1
投票

SQL Server提供row_number()功能:

select ID, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) RN FROM <TABLE_NAME>

编辑:

select * , case when (row_number() over (order by (select 1))) %3 = 0 then 3 else
           (row_number() over (order by (select 1))) %3 end [rn] from table

0
投票

我认为您的样本存在问题,因为您有隐含的订单但不是明确的订单。无法保证数据库将按照列出的方式保存和存储值,因此必须有一些固有/显式排序机制来告诉数据库以完全按照您列出的方式返回这些值。

例如,如果你这样做:

update test
set val = val + 2
where val < 3

你会发现你的select *不再以你预期的方式回来了。

你表示你的实际桌子是巨大的,所以我假设你有这样的东西你可以使用。表中应该有一些东西来表示你想要的顺序......时间戳,也许或者可能是代理键。

也就是说,假设你有类似的东西并且可以利用它,我相信一系列的窗口函数会起作用。

with rowed as (
  select
    val,
    case
      when lag (val, 1, -1) over (order by 1) = val then 0
      else 1
    end as idx,
    row_number() over (order by 1) as rn  -- fix this once you have your order
  from
    test
),
partitioned as (
  select
    val, rn,
    sum (idx) over (order by rn) as instance
  from rowed
)
select
  val, instance, count (1) over (partition by instance order by rn)
from
  partitioned

此示例按照它们在数据库中列出的方式排序,但您可能希望更改row_number函数以适应您的实际排序机制。

1   1   1
1   1   2
1   1   3
2   2   1
2   2   2
2   2   3
3   3   1
3   3   2
3   3   3
1   4   1
1   4   2
1   4   3
2   5   1
2   5   2
2   5   3
© www.soinside.com 2019 - 2024. All rights reserved.