2010-04-21 89 views
3

我有一个名为“名称”,“城市”和“职业”的三个填充列的表。 我想在同一个表中创建一个包含具有相同职业的人数的新列。SQL计数查询与多列分组

"Name" | "City" | "Occupation" 
------------------------------ 
Amy | Berlin | Plumber 
Bob | Berlin | Plumber 
Carol | Berlin | Lawyer 
David | London | Plumber 

我想有一个包含一个表:

"Name" | "City" | "Occupation" | "Number" 
--------------------------------------- 
Amy | Berlin | Plumber  | 2 
Bob | Berlin | Plumber  | 2 
Carol | Berlin | Lawyer  | 1 
David | London | Plumber  | 1 

如何创建新列的SQL查询有什么样子的?我想实际上在数据库中创建一个新的列,以便以后访问。

+0

我阅读标题奇迹为什么你的询问正在摸索......认真! – thecoshman 2010-04-21 10:00:11

+0

在上面的表格中,行是水平的,列是垂直的。例如“amy - berlin - plumber”是一排,而“Name”,“City”和“Occupation”是列。 – 2010-04-21 11:15:53

回答

1

简单的自联接:

SELECT t0.Name, t0.City, t0.Occupation, COUNT(*) AS Number 
FROM sometable AS t0 
JOIN sometable AS t1 ON t1.Occupation=t0.Occupation 
GROUP BY t0.Name, t0.City, t0.Occupation 

如果Name是主键,您可以只用单独代替组,因为其他列会对它的功能依赖。当然Name通常不会是一个非常好的主键。

(如果你想的其他人做的工作,而不是总的数量,您可能需要COUNT(*)-1目前还不清楚;在你的榜样的数字对不上任何一种方式)

如果您必须改变你的架构(除非你是你需要它绝对肯定我不会推荐这种denormalisation的;见注释),你可以用一个UPDATE做它加入到迈克尔的子查询:

ALTER TABLE sometable ADD COLUMN Number INTEGER NOT NULL; 
UPDATE sometable AS t0 JOIN (
    SELECT Occupation, COUNT(*) AS Number 
    FROM sometable 
    GROUP BY Occupation 
) AS t1 ON t1.Occupation=t0.Occupation 
SET t0.Number= t1.Number; 
+0

谢谢,但我想将Number写入行,因为它可能会花费很多 – Christian 2010-04-21 10:07:20

+2

不成熟的优化:在你需要的时候不要改变你的模式,通过'Occupation'上的索引,这个速度会非常快,我可以做一个类似的自连接,并且 - 在大约5秒的网页论坛数据库中查询500k个帖子,Michael的查询速度更快(尽管对于LIMITed结果,速度更慢);这最好取决于数据库中的确切数据,但是合适的索引将会很快 – bobince 2010-04-21 10:11:27

+0

我在我的数据库中有20,000,000个条目,我正在寻找100,000个查询,我需要性能。 – Christian 2010-04-21 11:39:26

3
select tbl.name, tbl.city, tbl.occupation, x.number 
from tbl 
join 
(
    select occupation, count(*) as number 
    from tbl 
    group by occupation 
) as x on x.occupation = tbl.occupation