我搜索了论坛,当我看到类似的帖子时,他们只讨论我需要制定的完整查询的部分(array_aggr,存在,加入等)。如果我已经回答了我发布的问题,我很乐意接受对这些帖子的引用。
我找到了this thread ...这与我需要的非常相似,除了它是针对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 - 每个user_id最多可以有15个attrib_id' s
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' ' WHEN'中的模式匹配条件(与ua.value相反),但一切都以“FALSE”结束。值。将开始一个新的问题,看看如果我无法理解它是否可以合并。谢谢大家的帮助!
答案 0 :(得分:3)
如果每个属性只有一个用户的值,您可以从制作稀疏矩阵开始:
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;
答案 1 :(得分:1)
从Postgres 9.4 开始,您可以使用更简单的aggregate FILTER
clause:
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+)。详情如下:
答案 2 :(得分:0)
这样的事情:
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)