如何向表添加列数并仍保留原始行?

问题描述 投票:0回答:7

我有一个名为 GUYS(ID, NAME, PHONE) 的表,我需要添加有多少个同名的人的计数,并同时显示所有这些人。所以我无法将它们分组。

示例:

ID NAME  PHONE
1  John  335   
2  Harry 444
3  James 367
4  John  742
5  John  654

期望的输出应该是:

ID NAME  PHONE COUNT
1  John  335   3
2  Harry 444   1
3  James 367   1
4  John  742   3
5  John  654   3

我怎么能这么做呢?我只找到了很多不同数量的人。

谢谢

sql mysql aggregate-functions
7个回答
42
投票

8.0+ 的更新:这个答案是在 MySQL 版本 8 之前写的,它引入了窗口函数,其语法与 Oracle 中现有的语法基本相同。

在这个新语法中,解决方案是

SELECT
  t.name,
  t.phone,
  COUNT('x') OVER (PARTITION BY t.name) AS namecounter
FROM
  Guys t

下面的答案仍然适用于较新的版本,在这种特殊情况下也同样简单,但根据具体情况,这些窗口函数更容易使用。


旧版本:从 MySQL 开始,直到版本 8,没有像 Oracle 那样的分析功能,你必须求助于子查询。

不要使用

GROUP BY
,使用子选择来计算同名的人的数量:

SELECT
  t.name,
  t.phone,
  (SELECT COUNT('x') FROM Guys ct 
   WHERE ct.name = t.name) as namecounter
FROM
  Guys t

您可能认为对每一行运行子选择会很慢,但如果您有适当的索引,MySQL 将优化此查询,您会发现它运行得很好。

在此示例中,您应该在

Guys.name
上有一个索引。如果子查询的
where
子句中有多个列,则查询可能会受益于所有这些列上的单个组合索引。


36
投票

使用聚合查询:

select g.ID, g.Name, g.Phone, count(*) over ( partition by g.name ) as Count
from 
Guys g;

20
投票

您仍然可以使用

GROUP BY
进行计数,只需将
JOIN
返回到原始表即可获取所有记录,如下所示:

select g.ID, g.Name, g.Phone, gc.Count
from Guys g
inner join (
    select Name, count(*) as Count
    from Guys
    group by Name
) gc on g.Name = gc.Name

0
投票

在 Oracle DB 中您可以使用

SELECT ID,NAME,PHONE,(Select COUNT(ID)From GUYS GROUP BY Name)
FROM GUYS ;


0
投票
DECLARE @tbl table 
(ID int,NAME varchar(20), PHONE int)
insert into @tbl
select 
1  ,'John',  335   
union all
select 
2  ,'Harry', 444
union all
select 
3  ,'James', 367
union all
select 
4  ,'John',  742
union all
select 
5  ,'John',  654

SELECT
 ID
 , Name
 , Phone
 , count(*) over(partition by Name)
FROM @tbl 
ORDER BY ID

-1
投票
select id, name, phone,(select count(name) from users u1 where u1.name=u2.name) count from users u2

-1
投票

尝试

select column1, count(1) over ()
© www.soinside.com 2019 - 2024. All rights reserved.