Postgresql 使用多表子句将多行值选择到单行中

Postgresql 使用多表子句将多行值选择到单行中,postgresql,select,aggregate-functions,aggregate-filter,Postgresql,Select,Aggregate Functions,Aggregate Filter,我已经搜索了论坛,虽然我看到了类似的帖子,但它们只涉及我需要制定array_aggr的完整查询的一部分、存在的位置、连接等。。如果我发布的问题已经得到了回答,我将很乐意接受对这些线程的引用 我确实找到了…这与我所需要的非常相似,除了MySQL,我一直在尝试将其转换为psql语法时出错。希望有人能帮我把一切都整理好。以下是场景: 属性 用户属性 下面是一个数据的小示例: 属性 UserAttribute-每个用户id最多可以有15个属性id/值 user_id | attrib_id | valu

我已经搜索了论坛,虽然我看到了类似的帖子,但它们只涉及我需要制定array_aggr的完整查询的一部分、存在的位置、连接等。。如果我发布的问题已经得到了回答,我将很乐意接受对这些线程的引用

我确实找到了…这与我所需要的非常相似,除了MySQL,我一直在尝试将其转换为psql语法时出错。希望有人能帮我把一切都整理好。以下是场景:

属性

用户属性

下面是一个数据的小示例:

属性

UserAttribute-每个用户id最多可以有15个属性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
这是我要找的

结果

如图所示,我正在查找包含以下内容的单行: -UserAttribute表中的用户\u 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;

在此基础上,我尝试在“WHEN”条件中针对ua.value添加一些“LIKE”模式匹配,但所有结果都是“FALSE”值。我将开始一个新的问题,看看如果我不能弄明白的话,这个问题是否可以被纳入。谢谢大家的帮助

如果每个属性对于一个用户只有一个值,则可以从创建稀疏矩阵开始:

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;

如果每个属性对于用户只有一个值,则可以从创建稀疏矩阵开始:

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;

像这样的东西怎么样:

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 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)
从Postgres 9.4开始,您可以使用更简单的:

要获得更多属性或最佳性能,请查看附加模块tablefunc Postgres 8.3+中的交叉表。详情如下:

从Postgres 9.4开始,您可以使用更简单的:

要获得更多属性或最佳性能,请查看附加模块tablefunc Postgres 8.3+中的交叉表。详情如下:



你犯了什么错误?您尝试的查询是什么?请编辑您的问题以显示这些内容,例如您想要某种透视表。我不确定我是否理解。。如果一个客户有15个属性,你需要15列吗?@Bohemian-我收到了分组依据和无效引用错误。我在执行嵌套的子查询/连接路径时运气不佳。@JoeLove-我不需要全部15个属性,只需要两个属性。您遇到了什么错误?您尝试的查询是什么?请编辑您的问题以显示这些内容,例如您想要某种透视表。我不确定我是否理解。。如果一个客户有15个属性,你需要15列吗?@Bohemian-我收到了分组依据和无效引用错误。我走嵌套子查询/连接路线时运气不佳。@JoeLove-我不需要全部15个属性,只需要两个属性。这是一个很好的起点!我不确定我会一个人来这里。基于属性表中的attrib_名称进行过滤会复杂多少,因为我正在查询的db实例之间的ID可能不同?另外,若要添加包含“string”的if值,请返回此值。我尝试在“WHEN”条件中针对ua.value添加一些“LIKE”模式匹配,但所有结果都是“FALSE”值。在这种情况下有可能这样做吗?如果没有,我将在PHP代码中处理正则表达式。@vmoralito:几乎任何事情都有可能。但请不要在评论中提问。更新你的问题或只是开始一个新的问题。这是一个伟大的起点!我不确定我会一个人来这里。基于属性表中的attrib_名称进行过滤会复杂多少,因为我正在查询的db实例之间的ID可能不同?另外,若要添加包含“string”的if值,请返回此值。我尝试在“WHEN”条件中针对ua.value添加一些“LIKE”模式匹配,但所有结果都是“FALSE”值。在这种情况下有可能这样做吗?如果没有,我将在PHP代码中处理正则表达式。@vmoralito:几乎任何事情都有可能。但请不要在评论中提问。更新您的问题或只是开始一个新问题。在调整以匹配实际表名后对此进行了尝试,但我得到以下错误:错误:列a.value不存在第1行:select ua.user_id、a.value attrib_value1、a2.attrib_Value2必须在select中添加一些逗号,然后重新命名表,但现在我得到了:错误:列a.atribute_id不存在第3行:left jo
在a.atribute_id=ua.attribute_id a上的ccs_属性a中,我必须进行更多的编辑以使其正常工作。此查询已执行,但未得到预期结果:选择ua.user\u id、a.name、ua.value、a2.name、,ua2.1.2中来自ccs_用户_属性ua的值左加入a.attribute_id=ua.attribute_id和a.attribute_id在ua2中左加入ccs_用户_属性ua2.user_id=ua.user_id和ua2.attribute_id>ua.attribute_id在a2中左加入ccs_属性a2.attribute_id=ua2.attribute_id和a2.attribute_id在1,2中;这也使我无法了解attrib_id,而attrib_id在不同的实例中会有所不同。如果出现语法错误,请选择ua.user_id、a.attrib_name attrib_value1、a2.attrib_name a2.attrib_value_2,以了解您在这里执行的操作。请注意,attrib_value1在任何地方都不作为列存在,这正是我希望结果表显示的内容。也许如果我们有一把小提琴玩会更容易。希望这一个能解决问题,我只是对同一个表进行几个连接,以获得每个属性。抱歉,响应延迟太长。在调整以匹配实际表名后对此进行了尝试,但我得到以下错误:错误:列a.value不存在第1行:select ua.user\U id、a.value attrib\U value1、a2.attrib\U value\U 2必须在select中添加一些逗号,然后重新命名表,但现在我得到了这样的结果:错误:列a.atribute\u id不存在第3行:左连接a.atribute\u id=ua.attribute\u id a上的ccs\u属性a…我必须再做一些编辑以使其正常工作。此查询已执行,但未得到预期结果:选择ua.user\u id、a.name、ua.value、a2.name、,ua2.1.2中来自ccs_用户_属性ua的值左加入a.attribute_id=ua.attribute_id和a.attribute_id在ua2中左加入ccs_用户_属性ua2.user_id=ua.user_id和ua2.attribute_id>ua.attribute_id在a2中左加入ccs_属性a2.attribute_id=ua2.attribute_id和a2.attribute_id在1,2中;这也使我无法了解attrib_id,而attrib_id在不同的实例中会有所不同。如果出现语法错误,请选择ua.user_id、a.attrib_name attrib_value1、a2.attrib_name a2.attrib_value_2,以了解您在这里执行的操作。请注意,attrib_value1在任何地方都不作为列存在,这正是我希望结果表显示的内容。也许如果我们有一把小提琴玩会更容易。希望这一个能解决问题,我只是对同一个表进行几个连接,以获得每个属性。很抱歉,回复延迟了很长时间。我现在锁定了9.1.3支持的供应商,但感谢您的评论。我将标记这些引用。我现在锁定在9.1.3支持的供应商,但感谢您的评论。我会把参考资料做好标记。
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;