簡體   English   中英

如何創建具有多個聚合函數計數和求和的視圖?

[英]How do I create a view with multiple aggregate functions count and sum?

我正在嘗試為我的Oracle表單創建摘要。 此摘要將存儲每個部門的員工人數。 記錄存儲在一個表中,該表將在不同的列中指示部門名稱(例如hr,it ...)代碼:

create table cleaners
(
ceno INTEGER,
cname VARCHAR(5)
);

create table drivers
(
eno INTEGER,
dname VARCHAR(5)
);

create table mechanics
(
eno INTEGER,
mname VARCHAR(5)
);

INSERT INTO cleaners VALUES ('1','3');
INSERT INTO cleaners VALUES ('2','3');
INSERT INTO cleaners VALUES ('3','3');
INSERT INTO cleaners VALUES ('4','2');
INSERT INTO cleaners VALUES ('5','2');

INSERT INTO drivers VALUES ('5','3');
INSERT INTO drivers VALUES ('4','3');
INSERT INTO drivers VALUES ('3','3');
INSERT INTO drivers VALUES ('2','2');
INSERT INTO drivers VALUES ('1','2');

INSERT INTO mechanics VALUES ('5','3');
INSERT INTO mechanics VALUES ('4','3');
INSERT INTO mechanics VALUES ('3','3');
INSERT INTO mechanics VALUES ('2','2');
INSERT INTO mechanics VALUES ('1','2');


create view summary as select
count(cleaners.eno) as numberofcleaners,
count(drivers.eno) as numberofdrivers,
count(mechanics.eno) as numberofmechanics,
from  cleaners, drivers, mechanics;

因此,我的目標是與每個部門的所有人員排成一行。 但是查詢返回相乘的結果。 應該怎么做? 我正在使用Oracle6i,這是一個沒有商業意義的學校項目。

由於這是一項家庭作業,因此我想提供一些有關如何以適當方式設計表格的信息。 只是我的兩分錢。

設計建議

我建議您更改表格設計。 您的所有表基本上都包含相同的數據:

  • 一個號碼
  • 名稱

與其擁有多個表,不如沿着這條線設計數據庫,使其僅包含兩個表。

Department
----------
dept_no   INTEGER
dept_name VARCHAR(30)

Person
------ 
person_no   INTEGER
person_name VARCHAR(30)
dept_no     INTEGER

創建具有約束的表

您應該設計具有適當約束的表。 這里有幾件事要注意。

  • 顧名思義,約束PRIMARY KEY會在表上創建一個主鍵,以保持數據唯一,這樣您就不會以具有相同值的多個ID結束。

  • 約束FOREIGN KEY在表Department和Person之間創建關系。

  • 對於此示例,這些鍵可能不是必需的,但在實際應用中,使用外鍵約束定義適當的關系始終是最佳實踐。 您可以在網絡上搜索有關PRIMARY KEYFOREIGN KEY許多其他信息。

  • 您不能切換創建這些表的順序。 換句話說,您不能先創建人員表,然后再創建部門表。 原因是Person表正在創建引用Department表的約束。 如果首先創建Person表,則會收到錯誤Failed: ORA-00942: table or view does not exist

  • 您也可以將dept_noperson_no設為自動遞增的數字,這樣就不必手動插入這些數字。 我使用SQL Server。 因此,我對使一列自動遞增數字的Oracle語法不太熟悉。 搜索Oracle的序列號,您可能會發現一些東西。

劇本

CREATE TABLE Department
(
    dept_no   INTEGER 
  , dept_name VARCHAR(30)
  , CONSTRAINT pk_department PRIMARY KEY (dept_no)
);

CREATE TABLE Person
(
    person_no   INTEGER
  , person_name VARCHAR(30)
  , dept_no     INTEGER
  , CONSTRAINT  pk_person PRIMARY KEY (person_no)
  , CONSTRAINT  fk_person_dept FOREIGN KEY (dept_no)
      REFERENCES Department (dept_no)
);

填充表格

  • 在給定腳本下面,首先填充Department表,然后填充Person表。

  • 實際上,它是在同一時間在表中插入多個值,而不是為每一行調用INSERT INTO。

  • dual是Oracle中的單表虛擬表。 請在此SO解答中閱讀有關雙重的內容。

劇本

INSERT ALL
  INTO Department (dept_no, dept_name) VALUES (1, 'Cleaner')
  INTO Department (dept_no, dept_name) VALUES (2, 'Driver')
  INTO Department (dept_no, dept_name) VALUES (3, 'Mechanic')
SELECT * FROM dual;

INSERT ALL
  INTO Person (person_no, person_name, dept_no) VALUES (1,  'Cleaner 1',   1)
  INTO Person (person_no, person_name, dept_no) VALUES (2,  'Cleaner 2',   1)
  INTO Person (person_no, person_name, dept_no) VALUES (3,  'Cleaner 3',   1)
  INTO Person (person_no, person_name, dept_no) VALUES (4,  'Cleaner 4',   1)
  INTO Person (person_no, person_name, dept_no) VALUES (5,  'Driver 1',    2)
  INTO Person (person_no, person_name, dept_no) VALUES (6,  'Driver 2',    2)
  INTO Person (person_no, person_name, dept_no) VALUES (7,  'Driver 3',    2)
  INTO Person (person_no, person_name, dept_no) VALUES (8,  'Mechanic 1',  3)
  INTO Person (person_no, person_name, dept_no) VALUES (9,  'Mechanic 2',  3)
  INTO Person (person_no, person_name, dept_no) VALUES (10, 'Mechanic 3',  3)
  INTO Person (person_no, person_name, dept_no) VALUES (11, 'Mechanic 4',  3)
  INTO Person (person_no, person_name, dept_no) VALUES (12, 'Mechanic 5',  3)
  INTO Person (person_no, person_name, dept_no) VALUES (13, 'Mechanic 6',  3)
SELECT * FROM dual;

如何將我的數據按部門分組?

  • 現在您已經有了表和數據,現在該查詢信息了。

  • 您的要求是獲取所有部門的清單以及每個部門的人數。

  • 如果運行以下查詢,您將僅獲得部門列表,但這不是您所需要的。

簡單選擇

SELECT  dept_no
    ,   dept_name 
FROM    Department;

輸出

DEPT_NO  DEPT_NAME
-------  ---------
   1     Cleaner
   2     Driver
   3     Mechanic
  • 因此,您可能會問:“ 我如何獲得該信息? '。 好吧,該信息在表Person中。 因此,我們需要將兩個表連接在一起以找到所需的數據。 我們將使用INNER JOIN將兩個表連接到一個公共字段上。 在這種情況下,兩個表中的公共字段均為dept_no

查詢將為您提供所需的輸出

劇本

SELECT      d.dept_no
        ,   d.dept_name 
        ,   COUNT(p.person_no) AS No_of_employees
FROM        Department d
INNER JOIN  Person p
ON          p.dept_no = d.dept_no
GROUP BY    d.dept_no
        ,   d.dept_name
ORDER BY    d.dept_no;

輸出

DEPT_NO  DEPT_NAME  NO_OF_EMPLOYEES
-------  ---------  ---------------
   1     Cleaner           4
   2     Driver            3
   3     Mechanic          6

說明

  • 該查詢使用了很多內容,例如INNER JOIN,GROUP BY,COUNT和ORDER BY。 讓我們看看其中的每一個。

  • INNER JOIN基於公共字段(在本例中為dept_no)聯接表。

  • COUNT函數將允許查詢組按員工的部門編號和部門名稱對所有員工進行計數。

  • COUNT是一個匯總函數。 當您將聚合函數與非聚合列一起使用時,則需要使用GROUP BY子句。 這里的dept_no和dept_name是非聚合列。 SUMMAX MIN是一些匯總函數。

  • 最后,我們應用ORDER BY子句按dept_no列對輸出進行排序。

演示版

單擊此處查看SQL Fiddle中的演示。

您正在查詢中進行交叉聯接。 試試這個:

create view summary 
    as 
    select 
    (select count(cleaners.eno) from cleaners) as numberofcleaners, 
    (select count(drivers.eno) from drivers ) as numberofdrivers, 
    (select count(mechanics.eno) from mechanics) as numberofmechanics
from dual;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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