2010-11-17 41 views
1

使用ORACLE SQL。SQL分组方式

我有一个表'Employees',其中一个属性'hire_date'。我的任务(书面练习)是写一个SELECT,告诉我在1995年,1996年,1997年和1998年有多少雇员被雇用。

喜欢的东西:

TOTAL  1995  1996  1997  1998 
----------------------------------------- 
20  4  5  29  2 

单独很容易算的员工数量每年,如:

SELECT 
    COUNT(*), 
FROM 
    employees e 
WHERE 
    e.hire_date like '%95' 

,但我有困难的时候我有“总”的数据以所需的格式。 有什么建议吗?

+0

练习是否说结果看起来应该是这样或者是您对“1995年,1996年雇用了多少雇员......”的解释? I.E.每年能有一排还是每年需要排成一排? – 2010-11-17 13:09:28

+0

为什么版本? 11g +支持ANSI PIVOT/UNPIVOT语法。 – 2010-11-17 18:19:58

回答

5

我假设你的聘用日期是VARCHAR2,因为你正在做一个在你的例子中“like”子句。

每年会有一排简单的桌子吗?

如果是的话,试试这个在甲骨文:

select case grouping(hire_date) 
      when 0 then hire_date 
      else 'TOTAL' 
     end hire_date, 
     count(hire_date) as count_hire_date 
from employees 
group by rollup(hire_date); 

这应该给这样的:

hire_date count_hire_date 
1995  10 
1996  20 
1997  30 
TOTAL  60 

如果您确实需要转动你的结果变得像你曾表示你的问题,那么如果您知道运行查询之前的不同年份,则可以执行以下操作。因此,举例来说,如果你知道你只在你的表有1995年,1996年和1997年,那么你可以使用转动的结果是:

SELECT 
    MAX(CASE WHEN hire_date = 'TOTAL' THEN ilv.count_hire_date END) total, 
    MAX(CASE WHEN hire_date = '1995'  THEN ilv.count_hire_date END) count_1995, 
    MAX(CASE WHEN hire_date = '1996'  THEN ilv.count_hire_date END) count_1996, 
    MAX(CASE WHEN hire_date = '1997'  THEN ilv.count_hire_date END) count_1997 
from (
    select case grouping(hire_date) 
      when 0 then hire_date 
      else 'TOTAL' 
      end hire_date, 
      count(hire_date) as count_hire_date 
    from employees 
    group by rollup(hire_date) 
) ilv; 

这你明显的缺点需要增加一个新的条款列入每个可能年份的主要选择声明。

+0

+1有关数据类型的好消息。 – 2010-11-17 14:37:55

1

下面是我如何在MS SQL中完成它 - 它在Oracle中会类似,但我不想尝试给你Oracle代码,因为我通常不会写它。这只是为了给你一个基本的骨架。

Select 
    Year(e.hire_date), 
    Count(1) 
From 
    employees e 
Group By 
    Year(e.hire_date) 
+0

年是没有必要或无效的。 – 2010-11-17 19:31:24

+0

你必须以某种方式获得一年。我从来没有说过它会在甲骨文中有效,但我确信有某种等价的东西。 – 2010-11-17 20:11:43

+1

TRUNC(date_col,'YYYY')是Oracle的等价物。 – 2010-11-18 02:45:53

1

以下是我会做它在MySQL,不知道这是否适用于甲骨文太:

SELECT 
YEAR(hire_date), COUNT(*) 
FROM 
employees 
GROUP BY 
YEAR(hire_date) 
+0

5分钟后 - 基本上和布兰登蒙哥马利一样建议 – 2010-11-17 13:02:41

+0

年是没有必要或没有效的。 – 2010-11-17 19:31:03

+0

TRUNC(date_col,'YYYY')是Oracle的等价物。 – 2010-11-18 02:45:36

1
SELECT NVL(hire_date,'Total'), count(hire_date) 
    FROM Employees GROUP BY rollup(hire_date); 

如果您需要PIVOT数据,请参阅A_M的答案。如果你有多年的你有没有数据,但仍希望今年有一个零计数,你可以这样做以下显示:

SELECT NVL(a.Year,b.Year), NVL2(a.Year,a.Count,0) FROM 
(
SELECT NVL(hire_date,'Total') Year, count(hire_date) Count 
    FROM Employees GROUP BY rollup(hire_date) 
) a 
FULL JOIN 
(
    SELECT to_char(2000 + rownum,'FM0000') Year FROM dual CONNECT BY rownum<=9 
) b ON a.Year = b.Year; 

下面是一些测试数据。

create table Employees (hire_date Varchar2(4)); 

insert into Employees values ('2005'); 
insert into Employees values ('2004'); 
insert into Employees values ('2006'); 
insert into Employees values ('2009'); 
insert into Employees values ('2009'); 
insert into Employees values ('2005'); 
insert into Employees values ('2004'); 
insert into Employees values ('2006'); 
insert into Employees values ('2006'); 
insert into Employees values ('2006'); 
4

语法不直观。它利用cut'n'paste编码:

SQL> select 
    2  sum(case when to_char(hiredate, 'YYYY') = '1980' then 1 else 0 end) as "1980" 
    3  , sum(case when to_char(hiredate, 'YYYY') = '1981' then 1 else 0 end) as "1981" 
    4  , sum(case when to_char(hiredate, 'YYYY') = '1982' then 1 else 0 end) as "1982" 
    5  , sum(case when to_char(hiredate, 'YYYY') = '1983' then 1 else 0 end) as "1983" 
    6  , sum(case when to_char(hiredate, 'YYYY') = '1987' then 1 else 0 end) as "1987" 
    7  , count(*) as total 
    8 from emp 
    9/

     1980  1981  1982  1983  1987  TOTAL 
---------- ---------- ---------- ---------- ---------- ---------- 
     1   10   1   0   2   20 

Elapsed: 00:00:00.00 
SQL> 
+0

+1,打我几秒 – 2010-11-17 13:07:02

+0

嗯,有人叮嘱我提供一个解决方案,它可以工作并以OP请求的格式生成结果集。我同意这个语法很丑,但那不是我的错。 – APC 2010-11-17 20:09:54

0

我意识到这是6年前,但我也发现了这样使用的是Oracle DECODE函数的另一种独特的方式。

select 
count(decode(to_char(hire_date, 'yyyy') , '2005', hire_date, null)) hired_in_2005, 
count(decode(to_char(hire_date, 'yyyy') , '2006', hire_date, null)) hired_in_2006, 
count(decode(to_char(hire_date, 'yyyy') , '2007', hire_date, null)) hired_in_2007, 
count(*) total_emp 
from employees 
where to_char(hire_date,'yyyy') IN ('2005','2006','2007')