SQL Group By子句如何划分查询结果

时间:2015-12-25 19:32:21

标签: sql oracle

我有下表:

enter image description here

当我运行此查询时:

Select Gender, City, SUM(Salary) as TotalSalary, COUNT(ID) as [Total Employees]
from tblEmployee 
Group by Gender, City

输出表是:

enter image description here

我对查询是如何整理员工感到困惑。我在查询中有Count(ID) as [Total Employees]但是SQL代码中的Group by子句如何划分总员工?因为我认为Count(ID) as [Total Employees]将返回10,因为我的表中有10条记录,但我不确定这个分组条款是如何平均分配总雇员的?是城市还是性别?

3 个答案:

答案 0 :(得分:2)

第一个SQL将您的表分成所有不同的性别(2),然后将这些组分成所有不同的城市(3)。

2 * 3 = 6,即有6个输出行。但是,没有伦敦女性,所以你得到5行输出。

查询的选择部分 - 包括计数(whatevers) - 按6组中的每一组完成。您无法在此查询中单独获得员工总数;你必须单独进行查询。

答案 1 :(得分:2)

有关分组的一般信息

取自Postgres documentationGROUP BY子句行为如下所述。

修改即可。在阅读@ lad2025评论后,我正在做一些澄清。是的,GROUP BY子句的解释引自特定的DBMS手册,但这些内容在我熟悉的所有不同数据库供应商中同样实现,因此从哪个供应商获取信息无关紧要这对你来说是可以理解的。

  

可选的 GROUP BY 子句具有以下一般形式:

GROUP BY expression [, ...]
     

GROUP BY会将共享的所有选定行压缩为一行   分组表达式的值相同。

     

[...]

     

如果使用了聚合函数,则会在构成每个组的所有行中计算聚合函数,从而为每个组生成单独的值。

回答您的问题

问题

  

我对查询是如何整理员工感到困惑。我在查询中将Count(ID)作为[Total Employees],但SQL代码中的Group by子句如何划分Total Employees?因为我认为Count(ID)作为[Total Employees]将返回10,因为我的表中有10条记录,但我不确定这个group by子句如何将员工总数平分?是城市还是性别?

回答

请记住,您为列指定的名称(作为别名)实际上不会影响此列中显示的行为和数据。对于包含TotalEmployees子句中的列的每个组,您的列id会计算列GROUP BY的每个出现次数。

在您的特定情况下,列(Gender, City)中的每个不同值对都会精简为一行。如果没有TotalEmployees列,这与将DISTINCT应用于您的查询的行为相同,因此以下两个呈现的查询都会产生相同的结果

1. Select Gender, City from tblEmployee Group by Gender, City;

2. Select Distinct Gender, City from tblEmployee;

回到您的问题,聚合函数COUNT(*)(以及该问题的任何聚合函数)将应用于整个分组表达式。这意味着以下两个查询都会产生相同数量的id列出现次数:

1. SELECT Count(ID) as [Total Employees] from tblEmployee;

2. SELECT SUM([Total Employees])
FROM (
  SELECT 
    Gender, City, SUM(Salary) as TotalSalary, COUNT(ID) as [Total Employees] 
  FROM 
    tblEmployee 
  GROUP BY Gender, City
  ) foo

答案 2 :(得分:1)

COUNT和其他聚合函数适用于GROUP BY子句指定的组中的行,而不是整个表。

  

<强> GROUP BY clause

     

GROUP BY子句是SelectExpression的一部分,它将结果分组到   具有一列或多列匹配值的子集。在每个列中   组,没有两行具有相同的分组列值或   列。对于分组目的,NULL被认为是等效的。

     

<强> Aggregate functions

     

根据组返回单个结果行   行,而不是单行。聚合函数可以出现在   选择列表以及ORDER BY和HAVING子句。它们通常是   与SELECT语句中的GROUP BY子句一起使用,其中Oracle   数据库将查询的表或视图的行划分为组。

enter image description here

根据您的情况,您可以根据GenderCity制作论坛。

           Gender   City        #
Blue:      Male     London      x5
Orange:    Female   New York    x2
Yellow:    Male     New York    x1
Brown:     Male     Sydney      x1
Olive:     Female   Sydney      x1

要获得整个表格的总COUNT,您可以使用带PARTITION BY的窗口函数:

SELECT DISTINCT
  Gender,
  City,
  SUM(Salary) OVER(PARTITION BY Gender, City) AS TotalSalary,
  COUNT(*) OVER(PARTITION BY Gender, City) AS EmployeePerGroup,
  COUNT(*) OVER() AS TotalEmployees
FROM tab

SqlFiddleDemo_Oracle SqlFiddleDemo_SQL_Server

输出:

╔═════════╦═══════════╦══════════════╦═══════════════════╦════════════════╗
║ GENDER  ║   CITY    ║ TOTALSALARY  ║ EMPLOYEEPERGROUP  ║ TOTALEMPLOYEES ║
╠═════════╬═══════════╬══════════════╬═══════════════════╬════════════════╣
║ Male    ║ London    ║       27300  ║                5  ║             10 ║
║ Female  ║ New York  ║        8500  ║                2  ║             10 ║
║ Male    ║ New York  ║        7000  ║                1  ║             10 ║
║ Male    ║ Sydney    ║        2800  ║                1  ║             10 ║
║ Female  ║ Sydney    ║        4800  ║                1  ║             10 ║
╚═════════╩═══════════╩══════════════╩═══════════════════╩════════════════╝