0

これをどのように表現するかは完全にはわかりませんが、誰かが助けてくれることを願っています. これが私の問題です。

次のフィールドを持つテーブル T があります

ID CF値
------------------------
976 13 重大度 1
978 36 ブランチ a  
978 13 重大度 1

属性ブランチが a で重要度が 1 のアイテムを取り出したい。

問題は、値フィールドが分​​岐と重大度の両方に使用され、異なる CF 値 13 または 36 によってのみ区別されることです。アイテムに両方の属性がある場合、重複したエントリが与えられます (たとえば、上記の ID 978)。

したがって、値 = 分岐 AND 値 = 重大度 1 である D から選択することはできません。

私がやりたいのは、次のフィールドを持つ Select - As - From です

ID ブランチの重大度

cf = 36 の場合は値フィールドを Branch にプルし、cf = 13 の場合は値を Severity にプルします。

しかし、これを構文的にどのように行うかはわかりません。Cases ステートメントと If ステートメントをいくつか試しましたが、エラーが発生し続けます。

どんな助けでも大歓迎です。

ありがとう。

4

3 に答える 3

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

このタイプの「デザイン」は「エンティティ属性値」パターンと呼ばれ、Catcall がすでに述べているように、アンチパターンと見なされます。物事を取得するための複雑な方法に正確です。

この言葉でネットで検索するとたくさんヒットします。

PostgreSQL では、tablefunc モジュールの crosstab 関数を使用することもできます。これは基本的に、上記のステートメントを関数内で動的に作成します。

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);
于 2012-05-22T17:47:32.810 に答える
0

このようにID番号を取得できます。

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

しかし、一般的に、より複雑なものはすべて結び目ができます。この種の構造はよく知られたアンチパターンであり、偶然ではありません。

于 2012-05-22T17:20:25.287 に答える
0

この種のスキーマを使用して簡単な操作を実行できます。

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

Catcall がすでに指摘したように、このシステムはしばらくするとかなり扱いにくくなる可能性があります。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 に対する余分な結合が削除されることを願っています。

于 2012-05-22T17:35:51.950 に答える