如何添加一个新列,该列将计算特定列的重复值数

时间:2016-07-12 13:33:51

标签: sql-server

我想添加一个新列,它将计算特定列的重复值数,并在表的第一个匹配行中显示计数结果。 例如,有下面的玩具表:

ID LOGIN NAME   COUNTRY
11 a@com  Aron  USA
12 a@com  Aron  Israel
13 ff@com Lucci Germany

我想在表的第一个出现行中获取LOGIN字段的计数:

ID LOGIN NAME   COUNTRY Count_LOGIN
11 a@com  Aron  USA         2
12 a@com  Aron  Israel      
13 ff@com Lucci Germany     1

我该怎么办? 我知道我可以将表保存为临时表,然后执行类似下面的操作,但这并不是我需要的。

SELECT LOGIN , COUNT(*) TotalCount
FROM #tt -- #tt is the first table 
GROUP BY LOGIN 
ORDER BY COUNT(*) DESC

3 个答案:

答案 0 :(得分:4)

首先,您可以使用ALTER TABLE添加新列Count_LOGIN。然后,使用带有子查询的UPDATE语句来填充该列。您问题中的查询可以看到您想要的内容。

ALTER TABLE #tt
ADD Count_LOGIN int;

UPDATE #tt
SET Count_LOGIN =
(
    SELECT COUNT(*)
    FROM #tt b
    WHERE #tt.LOGIN = b.LOGIN
    GROUP BY LOGIN
)

<强>更新

假设您只想更新LOGIN值最小的ID组的记录,可以尝试以下加入UPDATE查询:

UPDATE #tt
SET #tt.Count_LOGIN = t.TotalCount
FROM #tt
INNER JOIN
(
    SELECT LOGIN, MIN(ID) AS ID, COUNT(*) AS TotalCount
    FROM #tt
    GROUP BY LOGIN
) t
    ON #tt.ID = t.ID AND #tt.LOGIN = t.LOGIN

此查询只会影响原始#tt表中与每个ID组的最小LOGIN值匹配的记录。这会使该组中的其他记录没有值。

答案 1 :(得分:2)

create table #temp
(
id int,
loginn varchar(10),
name varchar(10),
cntry varchar(40)
)

insert into #temp
select 
11, 'a@com',  'Aron', 'USA'     union all
select 12, 'a@com',  'Aron',  'Israel'  union all
select 13, 'ff@com', 'Lucci', 'Germany'


;with cte
as
(
select *,ROW_NUMBER() over (partition by loginn order by id) as rn
 from #temp
 )
 select 
 id,loginn,name,cntry,
 case 
 when rn=1 then (select count(*) from cte  t1 where t1.loginn=t2.loginn) 
 else 0 
 end as duplicate
 from
cte t2

<强>输出:

id  loginn  name    cntry   duplicate
11  a@com   Aron    USA         2
12  a@com   Aron    Israel      0
13  ff@com  Lucci   Germany     1

答案 2 :(得分:2)

您可以尝试窗口函数来获取计数并决定何时显示结果。

SELECT
    Id
  , Login
  , Name
  , Country
  , COUNT(*) OVER (PARTITION BY Login) as Cnt
  , CASE WHEN 1 = ROW_NUMBER() OVER (PARTITION BY Login ORDER BY Id) -- (Order by need to match query Order statement)
         THEN COUNT(*) OVER (PARTITION BY Login) as Cnt
         ELSE NULL
    END AS Cnt_ONLY_ON_FIRST_RECORD
FROM #tt
ORDER BY 
    ID -- (Order by need to match Order in CASE condition statement)