0

不完全确定如何表达这一点,但希望有人能提供帮助。这是我的问题。

我有一个表 T 有以下字段

ID CF值
----------------------
976 13 严重性 1
978 36支一  
978 13 严重性 1

我想提取具有属性分支 a 和严重性 1 的项目。

问题是,value 字段同时用于分支和严重性,仅通过不同的 CF 值 13 或 36 进行区分。如果项目同时具有这两个属性,则会给出重复条目(例如上面的 ID 978)

所以我不能从 D 中选择,其中 value = branch a AND value = severity1。

我想要做的是一个 Select - As - From 与以下字段

ID 分支严重性

如果 cf = 36,则将 value 字段拉入 Branch,如果 cf = 13,则将 value 拉入 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 模块中的交叉表函数,它本质上是在函数内部动态创建上述语句。

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

使用 crosstab 函数,查询将如下所示:

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

您可以通过这种方式获得身份证号码。

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 回答