2010-09-30 46 views
3

此表格與正常模式相反,我不確定如何從中獲取所需的數據。如何使Oracle SQL查詢爲

下面是一些樣本數據,

Value (column)   Info (column) 
--------------------------------------------- 
Supplier_1    'Some supplier' 
Supplier_1_email  '[email protected]' 
Supplier_1_rating  '5' 
Supplier_1_status  'Active' 
Supplier_2    'Some other supplier' 
Supplier_2_email  '[email protected]' 
Supplier_2_rating  '4' 
Supplier_2_status  'Active' 
Supplier_3    'Yet another supplier' 

...

我需要一個查詢來找到具有最高等級,目前的狀態「有效」供應商的電子郵件。

+2

您可能希望創建一箇中介「供應商」的觀點,以幫助你自己和其他人將來會查詢這張表。 – 2010-09-30 20:17:02

+0

唉,我感到你的痛苦:) – 2010-10-01 03:59:38

+1

親愛的上帝,有人已經服用了EAV並使它變得更糟**。 – 2010-10-01 12:06:20

回答

2
select 
    m.sup_email, r.sup_rating 
from 
    (select substr(value, 1, length(value) - length('_email') as sup_name, info as sup_email from table where value like '%_email') as m 
left join 
    (select substr(value, 1, length(value) - length('_rating') as sup_name), info as sub_rating from table where value like '%_rating') as r on m.sup_name = r.sup_name 
order by 
    sup_rating desc 
limit 
    1; 
+0

哎呀,這正是我想弄清楚的......你錯過了'主動'標準,雖然... – 2010-09-30 19:53:52

+0

哇。當你發佈這個消息時,我正在編寫一個醜陋的回答,這改變了我的想法。您是否打算用供應商名稱替換「值」,或者Oracle是否足夠聰明,可以在計算連接時將其內部填充爲緩衝區變量? – 2010-09-30 19:57:01

+0

@OMG小馬:與您先計算供應商數量的方法相反,然後將新的UNION塊切割粘貼到每個查詢的每個塊上?哈哈...至少這個查詢比手工瀏覽數據庫更有效率,而不是那麼簡單! :) – 2010-09-30 20:02:31

0

擴大對Mike的指教:

CREATE VIEW supplier_names AS 
    SELECT SUBSTR(Value,INSTR(Value,'_')+1) AS supplier_id 
     ,Info AS supplier_name 
    FROM the_table 
    WHERE INSTR(Value,'_',1,2) = 0; 

CREATE VIEW supplier_emails AS 
    SELECT SUBSTR(Value,INSTR(Value,'_')+1,INSTR(Value,'_',1,2)-INSTR(Value,'_')-1) 
     AS supplier_id 
     ,Info AS supplier_email 
    FROM the_table 
    WHERE Value LIKE '%email'; 

CREATE VIEW supplier_ratings AS 
    SELECT SUBSTR(Value,INSTR(Value,'_')+1,INSTR(Value,'_',1,2)-INSTR(Value,'_')-1) 
     AS supplier_id 
     ,Info AS supplier_rating 
    FROM the_table 
    WHERE Value LIKE '%rating'; 

CREATE VIEW supplier_statuses AS 
    SELECT SUBSTR(Value,INSTR(Value,'_')+1,INSTR(Value,'_',1,2)-INSTR(Value,'_')-1) 
     AS supplier_id 
     ,Info AS supplier_rating 
    FROM the_table 
    WHERE Value LIKE '%status'; 

的查詢,將執行喜歡狗,所以我建議你考慮建立一些虛擬列,或者至少基於函數的索引,優化這些查詢。

1

對於單通的解決方案,嘗試:

select "email" from 
(select 
    substr("value", 1, 8 + instr(substr("value", 10, length("value")-9),'_')) "supplier", 
    max(case when "value" like '%_status' then "info" end) as "status", 
    max(case when "value" like '%_rating' then cast("info" as integer) end) as "rating", 
    max(case when "value" like '%_email' then "info" end) as "email" 
from "table" t 
where "value" like '%_rating' or "value" like '%_email' or "value" like '%_status' 
group by substr("value", 1, 8 + instr(substr("value", 10, length("value")-9),'_')) 
having max(case when "value" like '%_status' then "info" end) = 'Active' 
order by 3 desc 
) where rownum = 1 

(列名都用雙引號引起一些是保留字。)