分析用户资格数据的最佳方式(C# 和 SQL 服务器)
Optimal way to analyze user qualifications data (C# and SQL server)
我需要分析来自 SQL 服务器 table 的数据。 Table 包含与公司所有员工的资格相关的数据,并具有以下结构(简化):
| User | Qualification | DateOfQualificationAssignment |
| user000 | Junior | 2014-01-15 |
| user000 | Middle | 2014-02-15 |
| user001 | Middle | 2014-02-02 |
| user001 | Senior | 2014-03-18 |
| user002 | Senior | 2014-02-19 |
| user003 | Junior | 2014-03-04 |
我需要一种方法来确定在具体日期获得资格的员工人数。它应该是某种 analyze("Qualification", "Date") 函数,为这些类型的输入数据返回以下内容:
- analyze("Junior", '2014-01-20') - returns 1(用户user000)
- analyze("Junior", '2014-02-20') - returns 0(因为 user000 在 2014-02-15 成为中间人)
- analyze("Middle", '2014-02-25') - returns 2(因为 user000 和 user001 在 2014-02-25 有中等资格)
- analyze("Middle", '2014-03-28') - returns 1(user000 仍然是 Middle,但是 user001 在 2014-03-18 成为了 Senior)
目前我不知道如何有效地处理这个问题。可以使用什么方法来实现我的目标?
在派生的 table 中使用 row_number() over()
来枚举 DateOfQualificationAssignment descending
上由 User
分区的行,其中 DateOfQualificationAssignment
小于您想要的日期检查。
在主查询中,您计算具有枚举值 1
和 Qualification
.
的行
MS SQL Server 2012 架构设置:
create table T
(
[User] char(7),
Qualification char(6),
DateOfQualificationAssignment date
)
insert into T values
('user000', 'Junior', '2014-01-15'),
('user000', 'Middle', '2014-02-15'),
('user001', 'Middle', '2014-02-02'),
('user001', 'Senior', '2014-03-18'),
('user002', 'Senior', '2014-02-19'),
('user003', 'Junior', '2014-03-04')
查询 1:
declare @Qualification char(6) = 'Middle'
declare @Date date = '2014-03-28'
select count(*)
from (
select T.Qualification,
row_number() over(partition by T.[User] order by T.DateOfQualificationAssignment desc) as rn
from T
where T.DateOfQualificationAssignment < @Date
) as T
where T.rn = 1 and
T.Qualification = @Qualification
| COLUMN_0 |
|----------|
| 1 |
认为这应该能满足您的要求:
create function dbo.analyze(@qualification varchar(50), @date date)
returns int
as
begin
declare @result int;
with cte
as
(
select t.*, rank() over (partition by t.[User] order by t.DateOfQualificationAssignment desc) r
from theTable t -- no clue what the real table is named
where t.DateOfQualificationAssignment < @date
)
select @result = count(*)
from cte
where cte.r = 1 and cte.Qualification = @qualification
return @result;
end
go
使用您的数据测试:
create table theTable
(
[User] varchar(50) not null,
Qualification varchar(50) not null,
DateOfQualificationAssignment date not null
)
go
insert into theTable([User],Qualification,DateOfQualificationAssignment)
values
('user000','Junior','20140115'),
('user000','Middle','20140215'),
('user001','Middle','20140202'),
('user001','Senior','20140318'),
('user002','Senior','20140219'),
('user003','Junior','20140304')
go
结果:
select dbo.analyze('Junior','20140120') --returns 1
go
select dbo.analyze('Junior','20140220') --returns 0
go
select dbo.analyze('Middle','20140225') --returns 2
go
select dbo.analyze('Middle','20140328') --returns 1
go
我需要分析来自 SQL 服务器 table 的数据。 Table 包含与公司所有员工的资格相关的数据,并具有以下结构(简化):
| User | Qualification | DateOfQualificationAssignment |
| user000 | Junior | 2014-01-15 |
| user000 | Middle | 2014-02-15 |
| user001 | Middle | 2014-02-02 |
| user001 | Senior | 2014-03-18 |
| user002 | Senior | 2014-02-19 |
| user003 | Junior | 2014-03-04 |
我需要一种方法来确定在具体日期获得资格的员工人数。它应该是某种 analyze("Qualification", "Date") 函数,为这些类型的输入数据返回以下内容:
- analyze("Junior", '2014-01-20') - returns 1(用户user000)
- analyze("Junior", '2014-02-20') - returns 0(因为 user000 在 2014-02-15 成为中间人)
- analyze("Middle", '2014-02-25') - returns 2(因为 user000 和 user001 在 2014-02-25 有中等资格)
- analyze("Middle", '2014-03-28') - returns 1(user000 仍然是 Middle,但是 user001 在 2014-03-18 成为了 Senior)
目前我不知道如何有效地处理这个问题。可以使用什么方法来实现我的目标?
在派生的 table 中使用 row_number() over()
来枚举 DateOfQualificationAssignment descending
上由 User
分区的行,其中 DateOfQualificationAssignment
小于您想要的日期检查。
在主查询中,您计算具有枚举值 1
和 Qualification
.
MS SQL Server 2012 架构设置:
create table T
(
[User] char(7),
Qualification char(6),
DateOfQualificationAssignment date
)
insert into T values
('user000', 'Junior', '2014-01-15'),
('user000', 'Middle', '2014-02-15'),
('user001', 'Middle', '2014-02-02'),
('user001', 'Senior', '2014-03-18'),
('user002', 'Senior', '2014-02-19'),
('user003', 'Junior', '2014-03-04')
查询 1:
declare @Qualification char(6) = 'Middle'
declare @Date date = '2014-03-28'
select count(*)
from (
select T.Qualification,
row_number() over(partition by T.[User] order by T.DateOfQualificationAssignment desc) as rn
from T
where T.DateOfQualificationAssignment < @Date
) as T
where T.rn = 1 and
T.Qualification = @Qualification
| COLUMN_0 |
|----------|
| 1 |
认为这应该能满足您的要求:
create function dbo.analyze(@qualification varchar(50), @date date)
returns int
as
begin
declare @result int;
with cte
as
(
select t.*, rank() over (partition by t.[User] order by t.DateOfQualificationAssignment desc) r
from theTable t -- no clue what the real table is named
where t.DateOfQualificationAssignment < @date
)
select @result = count(*)
from cte
where cte.r = 1 and cte.Qualification = @qualification
return @result;
end
go
使用您的数据测试:
create table theTable
(
[User] varchar(50) not null,
Qualification varchar(50) not null,
DateOfQualificationAssignment date not null
)
go
insert into theTable([User],Qualification,DateOfQualificationAssignment)
values
('user000','Junior','20140115'),
('user000','Middle','20140215'),
('user001','Middle','20140202'),
('user001','Senior','20140318'),
('user002','Senior','20140219'),
('user003','Junior','20140304')
go
结果:
select dbo.analyze('Junior','20140120') --returns 1
go
select dbo.analyze('Junior','20140220') --returns 0
go
select dbo.analyze('Middle','20140225') --returns 2
go
select dbo.analyze('Middle','20140328') --returns 1
go