簡體   English   中英

SQL分組依據

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM