使用CASE表达式,而无需使用PostgreSQL手动输入匹配条件

nnvyjq4y  于 2023-02-15  发布在  PostgreSQL
关注(0)|答案(2)|浏览(112)

我有一个又长又宽的列表,下表只是一个例子。使用SQL的表结构可能看起来有点可怕,但我想知道是否有一种方法可以使用CASE表达式提取ID的价格,而无需键入列名以便在表达式中匹配
| 身份证|A_价格|B_价格|C_价格|...|
| - ------|- ------|- ------|- ------|- ------|
| A类|二十三|||...|
| B||六十五|八十二|...|
| C级||||...|
| A类|十个|||...|
| ......|...|...|...|...|
我想达到的目标表:
| 身份证|价格|
| - ------|- ------|
| A类|二十三岁;十岁|
| B|六十五|
| C级|八十二|
| ......|...|
我试过:

SELECT IDs, string_agg(CASE IDs WHEN 'A' THEN A_Price
                                WHEN 'B' THEN B_Price
                                WHEN 'C' THEN C_Price
                        end::text, ';') as price
FROM table
GROUP BY IDs
ORDER BY IDs

为了避免键入A、B、A_Price、B_Price等,我尝试格式化它们的名称并从子查询中调用它们,但SQL似乎无法将它们识别为列,也无法调用相应的值。

WITH CTE AS (
SELECT IDs, IDs||'_Price' as t FROM ID_list
)
SELECT IDs, string_agg(CASE IDs WHEN CTE.IDs THEN CTE.t
                        end::text, ';') as price
FROM table
LEFT JOIN CTE cte.IDs=table.IDs
GROUP BY IDs
ORDER BY IDs
uqdfh47h

uqdfh47h1#

您可以使用jsonhstore等文档类型作为过渡:
基本查询:

SELECT t.ids
     , to_json(t.*) ->> (t.ids || '_price') AS price
FROM   tbl t;

to_json()将整行转换为JSON对象,然后可以从中选择(动态连接的)键。
您的聚合:

SELECT t.ids
     , string_agg(to_json(t.*) ->> (t.ids || '_price'), ';') AS prices
FROM   tbl t
GROUP  BY 1
ORDER  BY 1;

转换整个(大?)行会增加一些开销,但无论如何,您必须为查询读取整个表。

gudnpqoy

gudnpqoy2#

在这里,工会是一种办法:

SELECT IDs, A_Price FROM yourTable WHERE A_Price IS NOT NULL
UNION ALL
SELECT IDs, B_Price FROM yourTable WHERE B_Price IS NOT NULL
UNION ALL
SELECT IDs, C_Price FROM yourTable WHERE C_Price IS NOT NULL;

相关问题