根据表中其他列的比较计算列

时间:2013-06-17 20:55:25

标签: sql-server database calculated-columns

好的我正在处理一个包含4列的数据库表,可以说是名字,中间名,姓氏和组ID 。我想根据他们拥有相同firstlast names而不管他们middle name的事实对人进行分组。我还想,如果有新条目,请为该条目提供正确的组ID。 以下是结果示例:

----------------------------------------------------------
|  First_Name |  Middle_Name  |  Last_Name  |  Group_ID  |
----------------------------------------------------------
|  Jon        |  Jacob        |  Schmidt    |   1        |
----------------------------------------------------------
|  William    |  B.           |  Schmidt    |   1        |
----------------------------------------------------------
|  Sally      |  Anne         |  Johnson    |   2        |
----------------------------------------------------------

我不确定这是否属于计算列的管辖范围,某种连接或更不明显的东西,请帮忙!

1 个答案:

答案 0 :(得分:1)

如果您只需要在查询中枚举群组,那么row_number()将适合您:

declare @Names table ( First_Name varchar(10), Middle_Name varchar(10), Last_Name varchar(10))
insert into @Names
    select 'Jon', 'Jacob', 'Schmidt' union all
    select 'William', 'B.', 'Schmidt' union all
    select 'Sally', 'Anne', 'Johnson' union all
    select 'Jon', 'Two', 'Schmidt'

;with Groups (First_Name, Last_Name, Group_ID) as
(   select  First_Name, Last_Name, row_number()over(order by Last_Name)
    from    @Names
    group
    by      First_Name, Last_Name
)
select  n.First_Name, n.Middle_Name, n.Last_Name, g.Group_Id
from    @Names n
join    Groups g on
        n.First_Name = g.First_Name and
        n.Last_Name = g.Last_Name;

请注意,Group_ID值将随着引入新的nameGroup而更改。

如果你想分配和坚持一个Group_ID,那么我建议你创建一个辅助表并在那里分配Group_ID。

通过将映射存储在@Names表之外,您可以允许用户更改其名称,而不必担心重新评估组分配。它还允许您修改分组逻辑,而无需重新分配名称。您还可以将类似的值映射到相同的分组(John,Jon,Jonny)。

Group_ID由First_Name和Last_Name组成。所以,以这种方式存储它。

declare @Names table ( First_Name varchar(10), Middle_Name varchar(10), Last_Name varchar(10))
insert into @Names
    select 'Jon', 'Jacob', 'Schmidt' union all
    select 'William', 'B.', 'Schmidt' union all
    select 'Sally', 'Anne', 'Johnson' union all
    select 'Jon', 'Two', 'Schmidt'

declare @NameGroup table (Group_Id int identity(1,1), First_Name varchar(10), Last_Name varchar(10) unique(First_Name, Last_Name));
insert into @NameGroup (First_Name, Last_Name)
    select 'Jon', 'Schmidt' union all
    select 'Sally', 'Johnson';


declare @Group_ID int;

declare @First_Name varchar(10), 
        @Middle_Name varchar(10),
        @Last_Name varchar(10)

select  @First_Name = 'Jon',
        @Middle_Name = 'X',
        @Last_Name = 'Schmidt'

--be sure the Id has already been assigned
insert into @NameGroup
    select @First_Name, @Last_Name
    where  not exists(select 1 from @NameGroup where First_Name = @First_Name and Last_Name = @Last_Name)

--resolve the id
select  @Group_ID = Group_ID 
from    @NameGroup 
where   First_Name = @First_Name and 
        Last_Name = @Last_Name;

--store the name
insert into @Names (First_Name, Middle_Name, Last_Name)
    values(@First_Name, @Middle_Name, @Last_Name);


select  n.First_Name, n.Middle_Name, n.Last_Name, ng.Group_Id
from    @Names n
join    @NameGroup ng on
        n.First_Name = ng.First_Name and
        n.Last_Name = ng.Last_Name;