在SELECT语句中,根据另一个列的数据类型设置一个字面量列的值
我想基于另一列值的数据类型(假设该列的值是字符串或数字),动态地把一个文本列的字面量设置为字符串或数字,以便在SELECT语句中使用。例如,我想生成一个 SELECT 'a' AS sortColumn FROM g_node 或 SELECT 1 AS sortColumn FROM g_node 的语句。
我有一个JSONB properties 列,其元素可以是数字或字符串。下面的CASE语句包含我想要的逻辑,区别在于第二个WHEN子句中我想把 'b' 改成数字1:
SELECT (jsonb_typeof(properties->'[variableElement]'))::text,
CASE (jsonb_typeof(properties->'[variableElement]'))::text
WHEN 'string' THEN 'a'
WHEN 'number' THEN 'b'
END AS sortColumn
FROM g_node
PostgreSQL对下列内容不予接受,因为它要求CASE子句中的所有值都属于相同的类型(该SQL无法工作):
SELECT (jsonb_typeof(properties->'[variableElement]'))::text,
CASE (jsonb_typeof(properties->'[variableElement]'))::text
WHEN 'string' THEN 'a'
WHEN 'number' THEN 1
END AS sortColumn
FROM g_node
因为CASE语句没成功,我想到或许可以创建一个变量,在动态生成的查询中使用该值,但下面的查询返回一个表,其列名为 result_val,行值为 'a' as sortColumn,类型为字符串:
CREATE OR REPLACE FUNCTION dynamic_select()
RETURNS TABLE(result_val TEXT) AS
$$
DECLARE
column_name TEXT := (SELECT
CASE (jsonb_typeof(properties->'name'))::text
WHEN 'string' THEN ('''a'' as sortColumn')::text
WHEN 'number' THEN ('1 as sortColumn')::text
END as sortColumn
FROM g_node LIMIT 1);
BEGIN
RETURN QUERY EXECUTE format('SELECT %L FROM g_node', column_name);
END;
$$ LANGUAGE plpgsql;
-- Usage
SELECT * FROM dynamic_select();
有没有其他用SQL的可行解决方案?理想情况下,如果不是太复杂,我想尽量在SQL内完成;否则我将使用Python脚本来构建查询。
解决方案
PostgreSQL对下列内容不予接受,因为它要求CASE子句中的所有值都属于相同的类型
是的。这不仅是Postgres的问题,也不仅是 CASE 子句的问题,而是SQL工作方式的一个根本特性。在每个查询中,返回的关系中的所有列都必须具有固定且预先确定的类型,随后返回的所有行必须包含恰好属于这些类型的值。
你可能需要运行两个独立的查询:
SELECT 1::int AS "sortColumn" FROM g_node WHERE jsonb_typeof(properties->'[variableElement]') = 'number';
SELECT 'a'::text AS "sortColumn" FROM g_node WHERE jsonb_typeof(properties->'[variableElement]') = 'string';
鉴于你已经在使用JSON,你也可能能够编写并执行一个返回类型为 json(b) 的列的单个查询,但是我还不太确定你到底想要什么。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。