5

If I have something like this in SQL statement ('A','B','C'), how do I convert it into a column with multiple rows like this

col
---
 A
 B
 C

I cannot change the way that string is created (as it is injected into SQL query from external program). For example, I cannot make it as ['A','B','C'] (replace with square brackets). I could wrap anything around it though like [('A','B','C')] or whatever.

Any help?

UPDATE 1

I have PostgreSQL 8.4.20

4
  • @jpmc26 No, not really. In my case, the constraint is the exact ('A','B','C') string I have to deal with. Commented May 22, 2018 at 21:12
  • I retracted the close vote before you said anything, but it apparently didn't delete the comment. Commented May 22, 2018 at 21:14
  • 1
    Your version of PG has not received security updates for almost 4 years. It's extremely important that you update to a supported version; this will also make a wide range of new features available to you. Commented May 22, 2018 at 21:27
  • Possible duplicate of unwrap postgresql array into rows Commented Mar 3, 2019 at 15:23

2 Answers 2

5

You could create an ARRAY from VALUES and then unnest it:

SELECT 
    unnest(ARRAY[col_a, col_b, col_c]) 
FROM 
    (VALUES('A','B','C')) AS x(col_a, col_b, col_c)

Result:

| unnest |
|--------|
|      A |
|      B |
|      C |

Edit: you could also tweak jspcal's answer by using dollar quotes ($$) like this so you can concatenate your string into the SQL statement:

  SELECT * FROM regexp_split_to_table(
    regexp_replace(
      $$('A','B','C','D','foo')$$,
      '^\(''|''\)+', '', 'g'),
      ''','''
    );
Sign up to request clarification or add additional context in comments.

7 Comments

This is very creative. I am doing more testing but look promising... :D Is it possible to have variable number of values? Like ('A','B','C','D','E') without knowing ahead of time?
This solution only works for a fixed number of columns. I am still searching for a more dynamic solution.
I've added a solution based on @jspcal's answer but using dollar quotes $$ to quote your string.
Awesome. We are getting to somewhere. I got the first row as ('A though. There is extra ('... Still monkeying around here.
@HP. select unnest(cast(translate($$( 'A','B','C','D','foo' )$$, '()''', '{}"') as text[])); dbfiddle.uk/…
|
2

The built-in regexp_split_to_table function will do this for you. Since you plan to inject it directly without escaping, use $$ (dollar quoting) from thibautg's answer.

select * from regexp_split_to_table(
    regexp_replace($$('A','B','C')$$, '^\(''|''\)+', '', 'g'),
    ''','''
);

8 Comments

If I do select regexp_split_to_table('A B C', E'\\s+');, it will work. But my original string is ('A','B','C'). So how to make it into 'A B C'?
You could strip the extraneous chars with regexp_replace.
I cannot change it to (''A'',''B'',''C'') but I can make it surrounded with quotes for example "('A','B','C')"
Take a look at the answer above that passes the original text to a function.
@HP. REPLACE: REPLACE(my_incoming_var, $$'$$, $$''$$). If you have control over any code here (which you must for your question to make even 1% sense), then you can do whatever the heck you want to the string.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.