2010-11-17 34 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')