我已经检查过了,之前我还没有找到这样的问题。
我有一个名为tests
的表,其中(简化)包含3列。
| id | name | expression |
=========================================
| 1 | width | |
| 2 | length | |
| 3 | area | [1] * [2] |
我需要一个查询,给定一个测试ID可以返回完全限定的表达式,即用相关名称替换表达式中的ID号。
表达式的ID号始终在方括号内。
我已经遵循了几条路径,但这是我当前的查询,但它并没有将名称替换为一个字符串。
查询:
WITH regexmatch AS
(
SELECT
id,
expression,
(regexp_matches(expression, '\[(\d+)\]', 'g'))[1] AS replaceid
FROM
test
WHERE
expression IS NOT NULL
AND
id = 3
GROUP BY
id, expression
)
SELECT
regexmatch.id,
regexmatch.expression,
REPLACE(regexmatch.expression, replaceid, (SELECT name FROM test WHERE id = replaceid::bigint))
FROM
regexmatch
输出:
| id | expression | replacement |
================================================
| 1 | [1] * [2] | [width] * [2] |
| 2 | [1] * [2] | [1] * [length] |
这个查询是否可行,如果可以,我该如何去做呢?
答案 0 :(得分:1)
一种方法是递归公用表表达式:
CREATE TABLE test(id INT, "name" VARCHAR(100), expression VARCHAR(100));
INSERT INTO test(id, "name", expression)
SELECT 1, 'width', NULL
UNION ALL SELECT 2, 'length', NULL
UNION ALL SELECT 3, 'area' , '[1] * [2]'
UNION ALL SELECT 4, 'height', NULL
UNION ALL SELECT 5, 'volume', '[3] * [4]'
UNION ALL SELECT 6, 'volumne_alt', '[2]^3';
查询:
WITH RECURSIVE cte AS (
SELECT id, expression::varchar(10000), "name"
,(regexp_matches(expression, '\[(\d+)\]'))[1] AS repid
FROM test
WHERE expression IS NOT NULL
UNION ALL
SELECT id, REPLACE(expression, repid, (SELECT name
FROM test
WHERE id = repid::int))::varchar(10000)
,"name",(regexp_matches(expression, '\[(\d+)\]'))[1]
FROM cte c
WHERE c.expression ~ '(.*)\[(\d+)\](.*)'
)
SELECT id, "name", expression
FROM cte
WHERE expression !~ '(.*)\[(\d+)\](.*)'
ORDER BY id;
的 SqlFiddleDemo
强>
输出:
╔═════╦══════════════╦════════════════════╗
║ id ║ name ║ expression ║
╠═════╬══════════════╬════════════════════╣
║ 3 ║ area ║ [width] * [length] ║
║ 5 ║ volume ║ [area] * [height] ║
║ 6 ║ volumne_alt ║ [length]^3 ║
╚═════╩══════════════╩════════════════════╝
使用表格UPDATE
:
WITH cte AS
(...
)
UPDATE test AS t
SET expression = c.expression
FROM cte AS c
WHERE t.id = c.id AND c.expression !~ '(.*)\[(\d+)\](.*)';
的 SqlFiddleDemo2
强>
输出:
╔═════╦══════════════╦════════════════════╗
║ id ║ name ║ expression ║
╠═════╬══════════════╬════════════════════╣
║ 1 ║ width ║ (null) ║
║ 2 ║ length ║ (null) ║
║ 3 ║ area ║ [width] * [length] ║
║ 4 ║ height ║ (null) ║
║ 5 ║ volume ║ [area] * [height] ║
║ 6 ║ volumne_alt ║ [length]^3 ║
╚═════╩══════════════╩════════════════════╝