0

For example I have two columns:

Column A: dog, cat, mouse

Column B: truck, jeep, lorry

I want a situation where:

Column C : dog, truck, cat, jeep, mouse, lorry

I am using Snowflake

2 Answers2

0

Assuming that columns colA, colB are strings, the values should be first splitted to atomic values SPLIT_TO_TABLE and combined again LISTAGG:

SELECT ID, COLA, COLB, LISTAGG(COL, ', ') AS colC
FROM (
  SELECT ID, COLA, COLB, TRIM(s1.VALUE::STRING) AS col
  FROM tab
  ,TABLE(SPLIT_TO_TABLE(tab.colA, ',')) AS s1
  UNION
  SELECT ID, COLA, COLB, TRIM(s2.VALUE::STRING) AS col
  FROM tab
  ,TABLE(SPLIT_TO_TABLE(tab.colB, ',')) AS s2
) AS sub
GROUP BY ID, COLA, COLB
ORDER BY ID;

For sample data:

CREATE OR REPLACE TABLE tab
AS
SELECT 1 AS id, 'dog, cat, mouse' AS colA, 'truck, jeep, lorry' AS colB UNION 
SELECT 2 AS id, 'sparrow' AS colA, 'sparrow, parrot' AS colB;

Output:

enter image description here


Sidenote: For storing non-atomic values ARRAY is a better choice:

CREATE OR REPLACE TABLE tab
AS
SELECT 1 AS id, ['dog', 'cat', 'mouse'] AS colA, ['truck', 'jeep', 'lorry'] AS colB UNION 
SELECT 2 AS id, ['sparrow'] AS colA, ['sparrow', 'parrot'] AS colB;

enter image description here

Then combining is a matter of using ARRAY_UNION_AGG:

SELECT ID, ARRAY_UNION_AGG(COL) AS COLC
FROM (
  SELECT ID, COLA AS col FROM tab
  UNION ALL
  SELECT ID, COLB AS col FROM tab
) sub
GROUP BY ID
ORDER BY ID;

Output:

enter image description here

Lukasz Szozda
  • 162,964
  • 23
  • 234
  • 275
  • I would prefer it not be an array. Both columns have individual rows. I would prefer a situation where : rows in column A come first on top in Column C, then rows in column B come second below in Column C or vice versa, OR any iteration or mixture of rows from column a and b being present in Column C , one after the other – Joshua Smart-Olufemi Sep 19 '22 at 13:21
0

Consider a UNION query:

SELECT 1 AS GrpID, FieldA AS Data FROM tablename
UNION SELECT 2, FieldB FROM tablename;
June7
  • 19,874
  • 8
  • 24
  • 34