[英]SQL Grouping By
使用ORACLE 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'
但是當我不得不以所需的格式“匯總”數據時,我遇到了困難。 有什么建議么 ?
我假設您的hirate_date是varchar2,因為您在示例中執行的是“ like”子句。
一張每年只有一行的簡單桌子會做嗎?
如果是這樣,請在Oracle中嘗試以下操作:
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;
這有一個明顯的缺點,那就是您需要在每個可能的年份中在主選擇語句中添加一個新子句。
語法不直觀。 這利用了“剪切粘貼”編碼:
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>
這就是我在MS SQL中的處理方式-在Oracle中將與之類似,但是我不想嘗試為您提供Oracle代碼,因為我通常不編寫它。 這只是讓您獲得基本骨架。
Select
Year(e.hire_date),
Count(1)
From
employees e
Group By
Year(e.hire_date)
這是我在MySQL中的處理方式,不知道這是否也適用於Oracle:
SELECT
YEAR(hire_date), COUNT(*)
FROM
employees
GROUP BY
YEAR(hire_date)
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');
我意識到這是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')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.