我有一个 SQL 表格,其中包含 JSON 格式的列。以下是 SQL 查询输出的示例:
我需要此表中的每一行将 JSON 对象和值扩展为包含相应数据的新列。
第一行的示例是一个名为“rate”的新列,其值将为“0.25”,而对于第二行,应创建名为“from”、“to”、“fixed”的其他列以及相应的值应存储在两个单独的行中,保持其余信息与查询本身相同。
这里的复杂性是数据集上的每一行都有不同的信息存储在“数据值”列(JSON 数据)中。
有什么方法可以使用查询或任何其他方法来执行此操作吗?
编辑: 添加我的 SELECT 语句以供参考,为每个对象添加一个新列,但这不适用于数组。
SELECT
port.id as "Port ID",
port.name as "Port Name",
country.name as "Country",
port_expense.id as "Port Expense ID",
port_expense.name::text as "Port Expense",
terminal.id as "Terminal ID",
terminal.name as "Terminal Name",
berth.id as "Berth ID",
berth.name as "Berth Name",
port_expense_formula_data.name as "Data Name",
port_expense_formula_data.value as "Data Value"
-- port_expense_formula_data.value::jsonb->>'from' as "From",
-- port_expense_formula_data.value::jsonb->>'to' as "To",
-- port_expense_formula_data.value::jsonb->>'unmoor' as "Unmoor",
-- port_expense_formula_data.value::jsonb->>'var' as "Var",
-- port_expense_formula_data.value::jsonb->>'tariff' as "Tariff",
-- port_expense_formula_data.value::jsonb->>'rate' as "Rate",
-- port_expense_formula_data.value::jsonb->>'lumpsum' as "Lumpsum",
-- port_expense_formula_data.value::jsonb->>'max' as "Max",
-- port_expense_formula_data.value::jsonb->>'min' as "Min",
-- port_expense_formula_data.value::jsonb->>'charge' as "Charge",
-- port_expense_formula_data.value::jsonb->>'day' as "Day",
-- port_expense_formula_data.value::jsonb->>'night' as "Night"
以及输出示例:
首先使用 jsonb_array_elements 展平表格以解除 JSON 数组的嵌套,并使用 横向连接 以便为每个数组元素生成一行。
SELECT
port.id as "Port ID",
port.name as "Port Name",
country.name as "Country",
port_expense.id as "Port Expense ID",
port_expense.name::text as "Port Expense",
terminal.id as "Terminal ID",
terminal.name as "Terminal Name",
berth.id as "Berth ID",
berth.name as "Berth Name",
port_expense_formula_data.name as "Data Name",
port_expense_formula_data.value as "Data Value"
j->>'from' as "From",
j->>'to' as "To",
j->>'unmoor' as "Unmoor",
j->>'var' as "Var",
j->>'tariff' as "Tariff",
j->>'rate' as "Rate",
j->>'lumpsum' as "Lumpsum",
j->>'max' as "Max",
j->>'min' as "Min",
j->>'charge' as "Charge",
j->>'day' as "Day",
j->>'night' as "Night"
from <your joined tables here>
cross join lateral
jsonb_array_elements(port_expense_formula_data.value::jsonb) j;