一、行轉(zhuǎn)列
近期在進(jìn)行MES項目的開發(fā),遇到了這樣的一個問題:
需求頁面是這樣的:
這是一個顯示生產(chǎn)線上設(shè)備狀態(tài)的頁面。注意紅框框住的幾列,這幾列是顯示設(shè)備參數(shù)的列,其并不是數(shù)據(jù)表中的列,而是由用戶定義在其他表中的數(shù)據(jù)行轉(zhuǎn)換而來的。(見下圖)。
在數(shù)據(jù)表中,與其相關(guān)的兩個表如下所示:
最后查詢出來的效果應(yīng)如下所示:
這里為了避免在傳輸過程中出現(xiàn)亂碼問題,將中文參數(shù),如“溫度”,用英文參數(shù)"STD_PARAM_1"代替。
所以,這就是一個行轉(zhuǎn)列問題。
解決這個問題需要分兩步進(jìn)行,要寫兩句SQL。
第一步先用一個Group By 查出參數(shù)表中有多少類需要參數(shù)。即為需要增加哪些類
"SELECT equ_param FROM MEA_EQUIP_TRUTH GROUP BY equ_param
查詢出的結(jié)果為'壓力'、'濕度'、'氣壓等'。
接下來需要使用Decode函數(shù)進(jìn)行行轉(zhuǎn)列,
轉(zhuǎn)化SQL如下所示:
SELECT
MAX(M.EQU_ID) EQU_ID,
MAX(M.EQU_NAME) EQU_NAME,
MAX(M.EQU_STATUS) EQU_STATUS,
SUM(DECODE(T.EQU_PARAM, '壓力', T.STD_VALUE)) STD_PARAM_1,
SUM(DECODE(T.EQU_PARAM, '壓力', T.ACT_VALUE)) ACT_PARAM_1,
SUM(DECODE(T.EQU_PARAM, '濕度', T.STD_VALUE)) STD_PARAM_2,
SUM(DECODE(T.EQU_PARAM, '濕度', T.ACT_VALUE)) ACT_PARAM_2,
SUM(DECODE(T.EQU_PARAM, '氣壓', T.STD_VALUE)) STD_PARAM_3,
SUM(DECODE(T.EQU_PARAM, '氣壓', T.ACT_VALUE)) ACT_PARAM_3,
SUM(DECODE(T.EQU_PARAM, '溫度', T.STD_VALUE)) STD_PARAM_4,
SUM(DECODE(T.EQU_PARAM, '溫度', T.ACT_VALUE)) ACT_PARAM_4
FROM MEA_POSITION_EQUIP M, MEA_EQUIP_TRUTH T
WHERE M.COMPANY_CODE = '00'
AND M.COMPANY_CODE = T.COMPANY_CODE(+)
AND M.LINE_CODE = T.LINE_CODE(+)
AND M.POSITION_CODE = T.POSITION_CODE(+)
AND M.ITEM_CODE = T.ITEM_CODE(+)
AND M.PRODUCT_LOT_NO = T.PRODUCT_LOT_NO(+)
AND M.EQU_ID = T.EQU_ID(+)
GROUP BY M.COMPANY_CODE,
M.LINE_CODE,
M.ITEM_CODE,
M.POSITION_CODE,
M.PRODUCT_LOT_NO,
M.EQU_ID,
M.EQU_NAME
這個SQL中包含如下一些Oracle數(shù)據(jù)庫的用法:
DECODE函數(shù)
DECODE 函數(shù)是實現(xiàn)行轉(zhuǎn)列功能的關(guān)鍵函數(shù)。其為Orcale中的獨有函數(shù)
SUM(DECODE(T.EQU_PARAM, '壓力', T.STD_VALUE)) STD_PARAM_1,
這一行的意思是T表中的參數(shù)EQU_PARAM,如果等于'壓力',則返回T表中相應(yīng)行STD_VALUE的值。
其中'壓力' 等值,可以在第一句SQL中查出。然后使用循環(huán)語句拼成上面的語句。這段循環(huán)可以寫在SP中,亦寫可以在JAVA中。
(+) 左右連接
關(guān)于(+)的用法 貼一篇網(wǎng)上的資料,介紹的很詳細(xì)。
關(guān)鍵是要記住
(+) 哪個表有加號,這個表就是匹配表。如果加號寫在右表,左表就是全部顯示,所以是左連接。
即右加號為左連接,左加號為右連接
二、Oracle 樹查詢
在工程上經(jīng)常會使用樹形結(jié)構(gòu),例如一級、二級、三級菜單 以及 ,省、市、縣等。樹形結(jié)構(gòu)的數(shù)據(jù)會以如下方式存儲在Oracle數(shù)據(jù)庫中:
及每個節(jié)點有一個存儲父節(jié)點ID的字段 PARENT_ID 。
像這種類型的存儲結(jié)構(gòu),Oracle有專門的關(guān)鍵字進(jìn)行查詢:
貼一個樹查詢講的比較好的博客oracle樹形查詢 start with connect by
select * from menu start with id='130000' connect by prior id = parent_id ;
對于樹查詢 關(guān)鍵是 對 關(guān)鍵字 prior 的理解。
prior 條件表示子數(shù)據(jù)需要滿足父數(shù)據(jù)的什么條件
prior放的左右位置決定了檢索是自底向上還是自頂向下. 左邊是自上而下(找子節(jié)點),右邊是自下而上(找父節(jié)點)
上面這條SQL的意義為,從ID = 130000 開始,如果有PARENT_ID 等于130000的全部查出來,然后遞歸。即父節(jié)點的ID等于子節(jié)點PARENT_ID的所有數(shù)據(jù)。這樣可以查出130000節(jié)點下的所有子節(jié)點。
三、查出表中所有的列:
一切查出表信息的常用SQL
select column_name from user_tab_cols where table_name='TAB';
1、查找表的所有索引(包括索引名,類型,構(gòu)成列):
select t.*,i.index_type from user_ind_columns t,user_indexes i where t.index_name = i.index_name and t.table_name = i.table_name and t.table_name = 要查詢的表
2、查找表的主鍵(包括名稱,構(gòu)成列):
select cu.* from user_cons_columns cu, user_constraints au where cu.constraint_name = au.constraint_name and au.constraint_type = 'P' and au.table_name = 要查詢的表
3、查找表的唯一性約束(包括名稱,構(gòu)成列):
select column_name from user_cons_columns cu, user_constraints au where cu.constraint_name = au.constraint_name and au.constraint_type = 'U' and au.table_name = 要查詢的表
4、查找表的外鍵(包括名稱,引用表的表名和對應(yīng)的鍵名,下面是分成多步查詢):
select * from user_constraints c where c.constraint_type = 'R' and c.table_name = 要查詢的表
查詢外鍵約束的列名:
select * from user_cons_columns cl where cl.constraint_name = 外鍵名稱
查詢引用表的鍵的列名:
select * from user_cons_columns cl where cl.constraint_name = 外鍵引用表的鍵名
5、查詢表的所有列及其屬性
select t.*,c.COMMENTS from user_tab_columns t,user_col_comments c where t.table_name = c.table_name and t.column_name = c.column_name and t.table_name = 要查詢的表
6、查詢所有表
select* from tabs