在网上进行了简短的搜索,看看是否已经存在答案。无法找到解决这种特殊情况的任何事情(这是一个惊喜,因为我认为这是相当普遍的。)
基本上我有一个表记录了服务的注册,以及客户注册的ID,以及注册的开始和结束日期。请参阅下面的表结构示例:
Reg ID | Client ID | Reg Start | Reg End
R6 C1 01-06-2016 Null
R5 C2 20-05-2016 02-06-2016
R4 C2 14-03-2016 11-05-2016
R3 C1 10-03-2016 05-05-2016
R2 C2 28-01-2016 02-02-2016
R1 C2 10-11-2015 23-12-2015
我想要做的是从表中提取记录,但也添加一个列,该列返回表中每个记录具有相同客户端ID的先前注册的数量。为了清楚起见,我只想计算具有相同客户ID并且开始日期小于记录的每条记录的注册。
因此,成功的查询将返回以下输出:
Reg ID | Client ID | Reg Start | Reg End | # previous reg
R6 C1 01-06-2016 Null 1
R5 C2 20-05-2016 02-06-2016 3
R4 C2 14-03-2016 11-05-2016 2
R3 C1 10-03-2016 05-05-2016 0
R2 C2 28-01-2016 02-02-2016 1
R1 C2 10-11-2015 23-12-2015 0
有没有人有过这样做的经验,可以提供可行的解决方案?
我最初的思考过程是创建一个子查询来计算按客户端ID分组的注册,然后使用客户端ID将其连接到我的主查询。例如:
SELECT
t1.reg_id
t1.client_id
t1.reg_start
t1.reg_end
FROM registrations t1
JOIN
(SELECT
client_id
count(reg_id)
FROM registrations
GROUP BY client_id) t2
ON t1.client_id = t2.client_id
但是,这将返回每个记录的给定客户端总注册的计数,其中我特别要求之前的注册。
蜂巢头脑可以提供的任何输入都将非常感激。我认为我在目前的SQL知识非常有限的情况下打了一针墙:/
另外我应该提一下,我正在使用Oracle数据库!
答案 0 :(得分:2)
您可以使用row_number()
:
select r.*,
(row_number() over (partition by client_id order by reg_start) - 1) as cnt
from registrations r;
答案 1 :(得分:2)
这可以通过窗口函数和运行总和来完成:
select reg_id, client_id, reg_start, reg_end,
count(*) over (partition by client_id order by reg_start) - 1 as previous_reg
from registrations
order by reg_start desc;
答案 2 :(得分:1)
在SQL Server中,您可以使用以下查询:
SELECT [Reg ID], [Client ID], Reg_Start, Reg_End,
COUNT(*) OVER (PARTITION BY [Client ID] ORDER BY Reg_Start) - 1
FROM mytable
COUNT
,当应用ORDER BY
子句时,返回记录计数的运行总计。如果这在Oracle中可用,那么它应该返回您想要的值。
答案 3 :(得分:0)
在我看来,最简单的方法是在主查询的SELECT
语句中构建子查询,如下所示:
SELECT
t1.*,
(
SELECT COUNT(*)
FROM registrations t2
WHERE t2.client_id = t1.client_id
AND t2.reg_start < t1.reg_start
) AS previous_reg
FROM registrations t1
ORDER BY reg_id DESC