首页 > 解决方案 > 从 jsonb 列中生成选定行之前和之后的行

问题描述

我想寻求帮助,因为我无法解决这个问题。我有这个结果是正确的。但它是表中真实物理数据的结果。

SELECT row_number() OVER (ORDER BY PR."Priority") AS "LOS", "SpeedLessThan", "SpeedAtLeast"
 FROM "ProjectRules" PR
 WHERE PR."ProjectId" = 500
   AND PR."Group" = 1;

在此处输入图像描述

好吧,问题是,现在我有一个不同的结构,其中物理行是 JSON。这个查询的结果是这样的。

SELECT row_number() OVER (ORDER BY MQ."Id") AS "LOS", "LevelOfServiceConfig"
 FROM "ProjectMqs" MQ
 WHERE MQ."ProjectId" = 500 AND "Id" = 1;

在此处输入图像描述

我需要生成一个与上面的结果完全相同的结果。所以这一行被分成 3 行,它的值要么小于零,要么大于 999。

SELECT "Id" as "LOS", "LevelOfServiceConfig" ->> 'Danger' AS "Danger", "LevelOfServiceConfig" ->> 'TrafficJam' AS "TrafficJam"
FROM "ProjectMqs"
WHERE "ProjectId" = 500
  AND NULLIF(regexp_replace("Name", '\D','','g'), '')::numeric = 1;

我不知道如何处理这个查询来获得结果。

标签: sqljsonpostgresqlselectjsonb

解决方案


您已经知道如何创建一行,只需使用UNION ALL或类似的构造来创建三行:

SELECT ROW_NUMBER() OVER (ORDER BY v.SpeedAtLeast) AS LOS, v.*
FROM t
CROSS JOIN LATERAL (VALUES
    (999, (t.LevelOfServiceConfig->>'Danger')::int),
    ((t.LevelOfServiceConfig->>'Danger')::int, (t.LevelOfServiceConfig->>'TrafficJam')::int),
    ((t.LevelOfServiceConfig->>'TrafficJam')::int, 0)
) AS v(SpeedLessThan, SpeedAtLeast)
ORDER BY LOS

推荐阅读