根据两列的相同值将 'iteration number' 列添加到 SQL Select

Add 'iteration number' column to SQL Select based on same values from two columns

我有一个 SQL(SQL 服务器)语句 SELECT id, animalId, ownerId FROM myTable ORDER BY id 输出以下数据:

id  | animalId | ownerId
------------------------
1   | 123      | 62
2   | 123      | 182
3   | 240      | 27
4   | 2        | 30
5   | 73       | 35
6   | 123      | 62
7   | 108      | 162
8   | 2        | 30
9   | 2        | 30
10  | 73       | 35

我想要做的是动态添加第四列,作为每一行的计数器,每行的 animalId 和 ownerId 具有相同的值。所以结果输出将是:

id  | animalId | ownerId | iterator
-----------------------------------
1   | 123      | 62      | 1           <-- First instance where animalId is 123 and ownerId is 62
2   | 123      | 182     | 1
3   | 240      | 27      | 1
4   | 2        | 30      | 1
5   | 73       | 35      | 1
6   | 123      | 62      | 2           <-- Second instance where animalId is 123 and ownerId is 62
7   | 108      | 162     | 1
8   | 2        | 30      | 2
9   | 2        | 30      | 3
10  | 73       | 35      | 2

谁能告诉我如何解决这个问题?

非常感谢。

如果您特别想计算 123/62 对在给定点之前的出现次数(如代码中的注释所建议的那样),则可以使用累加和:

select t.*,
       sum(case when ownerid = 62 and animalid = 123 then 1 else 0 end) over (order by id) as iterator
from t;

更合理的是,您希望所有对都使用这个。所以,使用 row_number():

select t.*,
       row_number() over (partition by ownerid, animalid order by id) as iterator
from t;

您可以使用 window 函数 ROW_NUMBER():

SELECT id, animalId, ownerId,
       ROW_NUMBER() OVER (PARTITION BY animalId, ownerId ORDER BY id) iterator 
FROM myTable 
ORDER BY id

参见demo
结果:

> id | animalId | ownerId | iterator
> -: | -------: | ------: | -------:
>  1 |      123 |      62 |        1
>  2 |      123 |     182 |        1
>  3 |      240 |      27 |        1
>  4 |        2 |      30 |        1
>  5 |       73 |      35 |        1
>  6 |      123 |      62 |        2
>  7 |      108 |     162 |        1
>  8 |        2 |      30 |        2
>  9 |        2 |      30 |        3
> 10 |       73 |      35 |        2

假设您希望结果按 ID 顺序排列。 请在下面找到基于纯 ANSI SQL 语法的解决方案。

创建table

create table animalOwners( id int, animalId int , ownerId int );

**插入数据**

insert into animalOwners values (1,123,62);
insert into animalOwners values(2,123,182);
insert into animalOwners values(3,240,27);
insert into animalOwners values(4,2,30);
insert into animalOwners values(5,73,35);
insert into animalOwners values(6,123,62);
insert into animalOwners values(7,108,162);
insert into animalOwners values(8,2,30);
insert into animalOwners values(9,2,30);
insert into animalOwners values(10,73,35);

SQL 解法:

select
    id,
    animalID,
    ownerId,
    (
    select
        count(*)
    from
        animalOwners innerTable
        where innerTable.id <= outerTable.id
        and innerTable.animalId = outerTable.animalId
        and innerTable.ownerId = outerTable.ownerId ) as counter
from
    animalOwners outerTable
order by
    id;

如果你运行这你会得到预期的输出。

您要查找的术语是“窗口函数”。您可以对组中的成员进行排序 (row_number over (partition by columns order by columns),对组中的成员进行计数 (count(1) over (partition by column)),对它们进行排序,对它们求和,取平均值他们等等