2012-05-22 31 views
0

不完全確定如何對此進行描述,但希望有人能夠提供幫助。這是我的問題。如何在PostgreSQL中有條件地拖動特定字段

我有一個具有以下字段

 
ID  CF Value 
------------------------ 
976  13 Severity 1 
978  36 branch a 
978  13 severity 1 

我想拔出它具有的屬性分支和嚴重性1.

問題是,值字段用於項的表T對於分支和嚴重程度,只能通過不同的CF值13或36區分。如果項目具有兩個屬性,則會給出重複項(例如上面的ID 978)

因此,我無法從D其中value =分支AND值= severity1。

我想要做的是一個選擇 - 爲 - 從以下字段

 
ID Branch Severity 

,值場拉進店,如果CF = 36和值拉進嚴重性,如果CF = 13

但我不知道我會如何做到這一點在語法上。我已經嘗試了幾個案例和If語句,但不斷收到錯誤。

任何幫助非常感謝。

謝謝。

回答

0

您可以通過這種方式獲得身份證號碼。

select id 
from your_table 
where value = 'branch a' 
    or value = 'Severity 1' 
group by id 
having count(id) = 2 

但是總的來說,你會發現任何更復雜的東西都會把你打結。這種結構是衆所周知的反模式,這不是偶然的。

0

你可以做簡單的操作與這種模式的:

select id from t where cf = 36 and value = 'branch a' 
intersect 
select id from t where cf = 13 and value = 'severity1' 

正如噓聲已經指出的那樣,這個系統可以得到一段時間後,很笨重。如果值T中的ID是指這樣一些實體表E,那麼你可以創建一個視圖有點像這樣:

create view e_attrs as 
select e.id, t_36.value as branch, t_13.value as severity 
from e 
    left join t t_36 on t_36.id = e.id and t_36.cf = 36 
    left join t t_13 on t_13.id = e.id and t_13.cf = 36 

,然後希望加入消除(從PostgreSQL的9.1,我認爲)將刪除多餘的加入對T如果你在視圖上查詢。

+0

謝謝 - 交集正是我所需要的! – user1410747

1

做具有應付這樣的模式時,一個樞軸的標準方法是這樣的:

select id, 
     max(branch) as branch, 
     max(severity) as severity 
from (
    select id, 
      case 
      when cf = 36 then value 
      else null 
      end as branch, 
      case 
      when cf = 13 then value 
      else null 
      end as severity 
    from t 
) p 
group by id 

這種類型的「設計」的被稱爲「實體屬性值」模式和 - 作爲噓聲具有已經說過 - 被認爲是反模式。正是以複雜的方式來檢索事物。

如果你在互聯網上搜索這個詞,你會得到很多點擊。

在PostgreSQL中,您也可以使用tablefunc模塊中的交叉表函數,它基本上在函數內部動態地創建上述語句。

http://www.postgresql.org/docs/current/static/tablefunc.html

使用交叉功能,查詢應該是這樣的:

SELECT * 
FROM crosstab(
    'select id, cf, value 
    from t 
    where cf in (13,36) 
    order by 1,2'::text) 
AS ct(id integer, severity text, branch text); 
相關問題