选择带有多表的条款多行值分为单列(Select multiple row values into s

2019-10-21 20:04发布

我搜索了论坛,而我看到类似的帖子,他们只解决了完整的查询,我需要制定件(array_aggr,在那里存在,联接等)。 如果我张贴的问题已经回答了,我会很乐意接受这些线程引用。

我发现这个线程 ...这是非常相似,我需要的,但它是MySQL,和我一直运行到试图进入它psql的语法错误。 希望有人能帮助我得到的一切在一起。 这里的情景:

属性

attrib_id | attrib_name

UserAttribute

user_id | attrib_id | value

这是一个什么样的数据看起来像一个小例子:

属性

attrib_id | attrib_name
-----------------------
1         | attrib1
2         | attrib2
3         | attrib3
4         | attrib4
5         | attrib5

UserAttribute -最多可以有15周attrib_id的/值的每USER_ID

user_id | attrib_id | value
----------------------------
101     | 1         | valueA
101     | 2         | valueB
102     | 1         | valueC
102     | 2         | valueD
103     | 1         | valueA
103     | 2         | valueB
104     | 1         | valueC
104     | 2         | valueD
105     | 1         | valueA
105     | 2         | valueB

这里就是我要找的

结果

user_id    | attrib1_value | attrib2_value
--------------------------------------------------------
101        | valueA        | valueB
102        | valueC        | valueD
103        | valueA        | valueB
104        | valueC        | valueD
105        | valueA        | valueB

如图所示,我在寻找,包含单行: - 从UserAttribute表USER_ID - 从UserAttribute表属性值

注:我只需要在属性表从UserAttribute表属性值了两个特殊的属性名称

同样,任何帮助或参照现有的解决方案将不胜感激。


更新:

@ronin提供一个查询,得到所希望的结果:

SELECT ua.user_id
      ,MAX(CASE WHEN a.attrib_name = 'attrib1' THEN ua.value ELSE NULL END) AS attrib_1_val
      ,MAX(CASE WHEN a.attrib_name = 'attrib2' THEN ua.value ELSE NULL END) AS attrib_2_val
  FROM UserAttribute ua
  JOIN Attribute a ON (a.attrib_id = ua.attrib_id)
  WHERE a.attrib_name IN ('attrib1', 'attrib2')
  GROUP BY ua.user_id;

要建立对,我尝试添加一些“LIKE”模式“当”的条件(对ua.value)中的匹配,但作为“假”值的一切结束了。 将启动一个新的问题,看看我能不能算出它可以合并。 感谢所有帮助!

Answer 1:

如果每个属性只有一个用户一个值,你可以通过一个稀疏矩阵开始:

SELECT user_id
      ,CASE WHEN attrib_id = 1 THEN value ELSE NULL END AS attrib_1_val
      ,CASE WHEN attrib_id = 2 THEN value ELSE NULL END AS attrib_2_val
  FROM UserAttribute;

然后使用聚集函数压缩所述矩阵:

SELECT user_id
      ,MAX(CASE WHEN attrib_id = 1 THEN value ELSE NULL END) AS attrib_1_val
      ,MAX(CASE WHEN attrib_id = 2 THEN value ELSE NULL END) AS attrib_2_val
  FROM UserAttribute
  GROUP BY user_id;

为响应评论,搜索由属性名称,而不是ID:

SELECT ua.user_id
      ,MAX(CASE WHEN a.attrib_name = 'attrib1' THEN ua.value ELSE NULL END) AS attrib_1_val
      ,MAX(CASE WHEN a.attrib_name = 'attrib2' THEN ua.value ELSE NULL END) AS attrib_2_val
  FROM UserAttribute ua
  JOIN Attribute a ON (a.attrib_id = ua.attrib_id)
  WHERE a.attrib_name IN ('attrib1', 'attrib2')
  GROUP BY ua.user_id;


Answer 2:

在Postgres 9.4开始,你可以使用简单的汇总FILTER条款

SELECT user_id
      ,MAX(value) FILTER (WHERE attrib_id = 1) AS attrib_1_val
      ,MAX(value) FILTER (WHERE attrib_id = 2) AS attrib_2_val
FROM   UserAttribute
WHERE  attrib_id IN (1,2)
GROUP  BY 1;

对于以上几个属性或顶级性能更,看向crosstab()从附加模块tablefunc (Postgres的8.3+)。 详情点击此处:

  • PostgreSQL的交叉表查询


Answer 3:

什么是这样的:

select ua.user_id, a.attrib_name attrib_value1, a2.attrib_name attrib_value2
from user_attribute ua
left join attribute a on a.atribute_id=ua.attribute_id and a.attribute_id in (1,2)
left join user_attribute ua2 on ua2.user_id=ua.user_id and ua2.attribute_id > ua.attribute_id
left join attribute a2 on a2.attribute_id=ua2.attribute_id and a2.attribute_id in (1,2)


文章来源: Select multiple row values into single row with multi-table clauses