我想添加一个新列,它将计算特定列的重复值数,并在表的第一个匹配行中显示计数结果。 例如,有下面的玩具表:
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
答案 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)