Oracle橫表、縱表一點記錄
橫表就是普通的建表方式,如一個表結構爲:
主鍵、字段1、字段2、字段3。。。
如果變成縱表後,則表結構爲:
主鍵、字段代碼、字段值。
而字段代碼則爲字段1、字段2、字段3。
縱表對從數據庫到內存的映射效率是有影響的,但細一點說也要一分爲二:
縱表的初始映射要慢一些;
縱表的變更的映射可能要快一些,如果只是改變了單個字段時,畢竟橫表字段比縱表要多很多。
橫表的好處是清晰可見,一目瞭然,但是有一個弊端,如果現在要把這個表加一個字段,那麼就必須重建表結構。對於這種情況,在縱表中只需要添加一條記錄,就可以添加一個字段,所消耗的代價遠比橫表小,但是縱表的對於數據描述不是很清晰,而且會造成數據庫數量很多,兩者利弊在於此。所以,應 該把不容易改動表結構的設計成橫表,把容易經常改動不確定的表結構設計成縱表。
測試例子:
create table a(name varchar2(12),
math number,
englist number,chinese number);
插入兩行記錄:
張三 85 90 95
李四 90 85 86
轉行查詢語句:
Sql代碼
SELECT flag, MAX(李四) AS 李四, MAX(張三) AS 張三
FROM (SELECT decode(NAME, '李四', fensu) as 李四,
decode(NAME, '張三', fensu) AS 張三,
flag
FROM (SELECT a.NAME, a.math AS fensu, 'math' AS flag
FROM a
UNION ALL
SELECT a.NAME, a.englist AS fensu, 'englist' AS flag
FROM a
UNION ALL
SELECT a.NAME, a.chinese AS fensu, 'chinese' AS flag FROM a) b
ORDER BY NAME, flag, fensu)
GROUP BY flag
現有emp和dept表
EMP
empno number(4)
ename varchar2(10)
job varchar2(9)
mgr number(4)
hiredate date
sal number(7,2)
comm number(7,2)
deptno number(2)
DEPT
deptno number(2)
dname varchar2(14)
loc varchar2(13)
統計不同部門和工作的員工的總工資
實現橫標轉換爲縱表
decode實現
Sql代碼
select d.dname dname,
sum(decode(e.job, 'CLERK', e.sal, 0)) CLERK,
sum(decode(e.job, 'SALESMAN', e.sal, 0)) SALESMAN,
sum(decode(e.job, 'ANALYST', e.sal, 0)) ANALYST,
sum(decode(e.job, 'MANAGER', e.sal, 0)) MANAGER,
sum(decode(e.job, 'PRESIDENT', e.sal, 0)) PRESIDENT
from emp e
join dept d
on e.deptno = d.deptno
group by d.dname;
case when實現
select d.dname dname,
sum(
case e.job
when 'CLERK' then e.sal
else 0
end
) CLERK,
sum(
case e.job
when 'SALESMAN' then e.sal
else 0
end
) SALESMAN,
sum(
case e.job
when 'PRESIDENT' then e.sal
else 0
end
) PRESIDENT,
sum(
case e.job
when 'MANAGER' then e.sal
else 0
end
) MANAGER,
sum(
case e.job
when 'ANALYST' then e.sal
else 0
end
) ANALYST
from emp e
join dept d
on e.deptno = d.deptno
group by d.dname;
帶合計項的
select d.dname dname,
sum(decode(e.job, 'CLERK', e.sal, 0)) CLERK,
sum(decode(e.job, 'SALESMAN', e.sal, 0)) SALESMAN,
sum(decode(e.job, 'ANALYST', e.sal, 0)) ANALYST,
sum(decode(e.job, 'MANAGER', e.sal, 0)) MANAGER,
sum(decode(e.job, 'PRESIDENT', e.sal, 0)) PRESIDENT
from emp e
join dept d on e.deptno = d.deptno
group by d.dname
union
select '總計' dname,
sum(decode(e.job, 'CLERK', e.sal, 0)) CLERK,
sum(decode(e.job, 'SALESMAN', e.sal, 0)) SALESMAN,
sum(decode(e.job, 'ANALYST', e.sal, 0)) ANALYST,
sum(decode(e.job, 'MANAGER', e.sal, 0)) MANAGER,
sum(decode(e.job, 'PRESIDENT', e.sal, 0)) PRESIDENT
from emp e
join dept d2 on e.deptno = d2.deptno
主鍵、字段1、字段2、字段3。。。
如果變成縱表後,則表結構爲:
主鍵、字段代碼、字段值。
而字段代碼則爲字段1、字段2、字段3。
縱表對從數據庫到內存的映射效率是有影響的,但細一點說也要一分爲二:
縱表的初始映射要慢一些;
縱表的變更的映射可能要快一些,如果只是改變了單個字段時,畢竟橫表字段比縱表要多很多。
橫表的好處是清晰可見,一目瞭然,但是有一個弊端,如果現在要把這個表加一個字段,那麼就必須重建表結構。對於這種情況,在縱表中只需要添加一條記錄,就可以添加一個字段,所消耗的代價遠比橫表小,但是縱表的對於數據描述不是很清晰,而且會造成數據庫數量很多,兩者利弊在於此。所以,應 該把不容易改動表結構的設計成橫表,把容易經常改動不確定的表結構設計成縱表。
測試例子:
create table a(name varchar2(12),
math number,
englist number,chinese number);
插入兩行記錄:
張三 85 90 95
李四 90 85 86
轉行查詢語句:
Sql代碼
SELECT flag, MAX(李四) AS 李四, MAX(張三) AS 張三
FROM (SELECT decode(NAME, '李四', fensu) as 李四,
decode(NAME, '張三', fensu) AS 張三,
flag
FROM (SELECT a.NAME, a.math AS fensu, 'math' AS flag
FROM a
UNION ALL
SELECT a.NAME, a.englist AS fensu, 'englist' AS flag
FROM a
UNION ALL
SELECT a.NAME, a.chinese AS fensu, 'chinese' AS flag FROM a) b
ORDER BY NAME, flag, fensu)
GROUP BY flag
現有emp和dept表
EMP
empno number(4)
ename varchar2(10)
job varchar2(9)
mgr number(4)
hiredate date
sal number(7,2)
comm number(7,2)
deptno number(2)
DEPT
deptno number(2)
dname varchar2(14)
loc varchar2(13)
統計不同部門和工作的員工的總工資
實現橫標轉換爲縱表
decode實現
Sql代碼
select d.dname dname,
sum(decode(e.job, 'CLERK', e.sal, 0)) CLERK,
sum(decode(e.job, 'SALESMAN', e.sal, 0)) SALESMAN,
sum(decode(e.job, 'ANALYST', e.sal, 0)) ANALYST,
sum(decode(e.job, 'MANAGER', e.sal, 0)) MANAGER,
sum(decode(e.job, 'PRESIDENT', e.sal, 0)) PRESIDENT
from emp e
join dept d
on e.deptno = d.deptno
group by d.dname;
case when實現
select d.dname dname,
sum(
case e.job
when 'CLERK' then e.sal
else 0
end
) CLERK,
sum(
case e.job
when 'SALESMAN' then e.sal
else 0
end
) SALESMAN,
sum(
case e.job
when 'PRESIDENT' then e.sal
else 0
end
) PRESIDENT,
sum(
case e.job
when 'MANAGER' then e.sal
else 0
end
) MANAGER,
sum(
case e.job
when 'ANALYST' then e.sal
else 0
end
) ANALYST
from emp e
join dept d
on e.deptno = d.deptno
group by d.dname;
帶合計項的
select d.dname dname,
sum(decode(e.job, 'CLERK', e.sal, 0)) CLERK,
sum(decode(e.job, 'SALESMAN', e.sal, 0)) SALESMAN,
sum(decode(e.job, 'ANALYST', e.sal, 0)) ANALYST,
sum(decode(e.job, 'MANAGER', e.sal, 0)) MANAGER,
sum(decode(e.job, 'PRESIDENT', e.sal, 0)) PRESIDENT
from emp e
join dept d on e.deptno = d.deptno
group by d.dname
union
select '總計' dname,
sum(decode(e.job, 'CLERK', e.sal, 0)) CLERK,
sum(decode(e.job, 'SALESMAN', e.sal, 0)) SALESMAN,
sum(decode(e.job, 'ANALYST', e.sal, 0)) ANALYST,
sum(decode(e.job, 'MANAGER', e.sal, 0)) MANAGER,
sum(decode(e.job, 'PRESIDENT', e.sal, 0)) PRESIDENT
from emp e
join dept d2 on e.deptno = d2.deptno
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.