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 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章