如何将 PostgreSQL 行扩展为多行以更新“自定义字段”?

Posted

技术标签:

【中文标题】如何将 PostgreSQL 行扩展为多行以更新“自定义字段”?【英文标题】:How can I expand a PostgreSQL row into multiple rows for updating "custom fields"? 【发布时间】:2009-12-01 13:47:44 【问题描述】:

我有一个由一个第 3 方软件(比如 user_fields)使用的表,它的每一行都有一个 user_id、一个 field_id 和一个 field_value。我知道很糟糕。

我还有另一个我自己的用户表 users,它包含填充它所需的值,除了 field_id 它是“魔术”并且对应于自定义字段映射。

我怎样才能编写一个选择查询来实现这一点:

user_id | company_name       | first_name | country
---------------------------------------------------
1       | Nutty Choc Company | Si         | GB
2       | Ljubljanske R Us   | Pie        | IT

喜欢这个吗?

user_id | field_value        | field_id
---------------------------------------
1       | Nutty Choc Company | 10
1       | Si                 | 11
1       | GB                 | 12
2       | Ljubljanske R Us   | 10
2       | Pie                | 11
2       | IT                 | 12

我正在使用 Postgresql 8.4,并打算将查询提供给插入。

我通过使用 unnest 和数组来尝试将字段扩展为行,但它在处理选择中的任何其他字段后取消嵌套,因此只是复制未嵌套行的值。

有什么想法吗?

干杯, 硅

编辑:格式化和澄清狡猾的名称-值表是第 3 方。

【问题讨论】:

请缩进您的代码示例以增加可读性。 【参考方案1】:

我将此作为单独的答案添加,因为它与我发布的其他答案完全不同。你可以试试这样的:

SELECT
     U.id,
     UF.id AS field_id,
     CASE UF.id
          WHEN 10 THEN U.first_name
          WHEN 11 THEN U.country
          WHEN 12 THEN U.company_name
          ELSE NULL
     END AS field_value
FROM
     Users U
CROSS JOIN User_Fields UF

这是假设您有一个 User_Fields 表(或任何可能命名的表),它为您提供所有可能的用户字段。不过,您必须及时更新您的 CASE 声明。

【讨论】:

【参考方案2】:

我的第一个想法是摆脱名称-值对架构。在关系数据库中,您只是在寻找永无止境的麻烦,正如您已经开始看到的那样。

现在有了必要的责骂......

INSERT INTO My_Horrible_Name_Value_Pair_Table
(
     user_id,
     field_id,
     field_value
)
SELECT
     id,
     10,
     first_name
FROM
     Users
UNION ALL
SELECT
     id,
     11,
     country
FROM
     Users
UNION ALL
SELECT
     id,
     12,
     company_name
FROM
     Users

我相信您可以想象当您添加更多字段时,这会变得多么可怕。

【讨论】:

我确实可以想象。不幸的是,我无法控制名称-值对。我可能会尝试使用“with”查询,因为我需要一些可能很昂贵的底层连接。您认为有没有一种简单的方法可以将 10、11、12 作为重复值加入到未嵌套的值中?

以上是关于如何将 PostgreSQL 行扩展为多行以更新“自定义字段”?的主要内容,如果未能解决你的问题,请参考以下文章

pyspark RDD 将一行扩展为多行

Node.js 中的 PostgreSQL 多行更新

PostgreSQL:如何将多行的值放在不同的列中,并将所有值合并到一行中?

当多行满足要求时,如何通过连接在 PostgreSQL 中进行选择?

如何修改触发器以更新 PostgreSQL 中的单个属性

PostgreSQL如何对结果进行分组以使所有行都必须为真?