SQL Server: flatten an array [duplicate] - sql

This question already has answers here:
Unnest Arrays in SQL Server
(2 answers)
Closed last month.
I have a table that looks like this:
id my_array
-------------------------
1 ["a", "b", "c"]
I would like to flatten it so it looks like this:
id my_array
------------------------
1 "a"
1 "b"
1 "c"
I have tried with openjson() without success.

Try this:
SELECT
1 id,
value my_array
FROM STRING_SPLIT(replace(replace('["a", "b", "c"]','[',''),']',''),',');

DECLARE #T AS TABLE(id INT,Field VARCHAR(200))
INSERT INTO #T
SELECT 1 ,'["a", "b", "c"]'
UNION
SELECT 2 ,'["x", "y", "z"]'
SELECT A.id,LTRIM(REPLACE(REPLACE(REPLACE(B.value,'"',''),'[',''),']','')) AS my_array
FROM #T A
CROSS APPLY (SELECT * FROM STRING_SPLIT(Field,',')) B

Related

How to use LIKE with ANY in BigQuery?

I would like to use the LIKE ANY operator to exclude rows based on an array of substrings, but BigQuery does not recognize it.
declare unlaunched_clistings array<string>;
set unlaunched_clistings = {unlaunched_clistings} ;
select * from {p}.simeon_logs.process_errors e
where not e.message like any(unlaunched_clistings)
Error : LIKE ANY is not supported at [8:32]
Is there any workaround for this?
LIKE ANY is not supported, however you can use following 2 ways:
Use LIKE with ORs between them
WITH table AS (
SELECT 'abc' as col union all
SELECT 'xzy' as col
)
SELECT col
FROM TABLE
WHERE (col like '%abc%'
OR col like '%cde%' OR col like '%something%')
User RegEx
WITH table AS (
SELECT 'abc' as col
UNION ALL
SELECT 'xzy' as col
)
SELECT col
FROM TABLE
WHERE REGEXP_CONTAINS(col
, 'abc|cde|something')
Above both will give you abc row.

Calculate the number of values ​in each field separately in SQL

I have this table like this:
Column A
Column B
Column C
B
1
w
B
2
e
A
1
p
I want to get result like this:
Column
CountByValue
B
2
A
1
1
2
2
1
w
1
e
1
p
1
Is there any way to get the above result with SQL? Thanks.
It can be done like following also using CROSS APPLY
SELECT V.[Column],COUNT(*) CountByValue
FROM MyTable T
CROSS APPLY (
SELECT [Column]
FROM (
VALUES (T.ColumnA),(T.ColumnB),(T.ColumnC)) v([Column])
) v
GROUP BY V.[Column]
You can use APPLY, but you don't need a subquery:
SELECT V.[Column], COUNT(*)
FROM T CROSS APPLY
(VALUES (T.ColumnA), (T.ColumnB), (T.ColumnC)
) v(Column)
GROUP BY V.[Column]
If values are distinct between columns you need UNION ALL:
SELECT "Column A" AS "Column", COUNT() AS "CountByValue"
FROM "MyTable"
GROUP BY "Column A"
UNION ALL
SELECT "Column B", COUNT()
FROM "MyTable"
GROUP BY "Column B"
UNION ALL
SELECT "Column C", COUNT()
FROM "MyTable"
GROUP BY "Column C"

Concatenation in hive query

I have a hive table like
col1 col2
1 ["apple", "orange"]
1 ["orange", "banana"]
1 ["mango"]
2 ["apple"]
2 ["apple", "orange"]
There data types is
col1 int
col2 array<string>
I want to query something like :
select col1, concat(col2) from table group by col1;
Output should be :
1 ["apple", "orange", "banana", "mango"]
2 ["apple", "orange"]
Is there any function in hive to do this ?
Also I write this data to csv and when I read it as a dataframe I get the col2 dtype as object. Is there a way to output it as an array.
Try by exploding the array then use collect_set function by grouping by col1.
Example:
Input:
select * from table;
OK
dd.col1 dd.col2
1 ["apple","orange"]
1 ["mango"]
1 ["orange","banana"]
select col1,collect_set(tt1)col2 from (
select * from table lateral view explode(col2) tt as tt1
)cc
group by col1;
Output:
col1 col2
1 ["apple","orange","mango","banana"]

How to select multiple row in postgresql?

I can give a result set consisting of a single value, say 1, as follows:
SELECT 1 as column;
and it gives me the result set:
column
------
1
But I have a list of such values represented as a string (1, 4, 7, ...) and I need to produce the following result set:
column
------
1
4
7
.
.
.
I tried SELECT * FROM (1, 4, 7) but it didn't work. I also tried to SELECT 1, 4, 7 but it produces the following result set:
col1 col2 col3
1 4 7
Which was not what I was looking for.
If those are constant values, you can use the values clause:
select *
from (
values (1), (4), (7)
) as t(id);
If your values are inside a string literal, you can use this:
select *
from unnest(string_to_array('1,2,3,4', ',')) as id;
You could unnest it as an array:
SELECT UNNEST(ARRAY[1, 4, 7])
You can use the union To get what you want.But if this is the sting as 1,4,7 comma seprated then you need to use the regexp_split_to_table function. Mentioned here and here
Select 1
UNION
select 4
UNION
select 7

From a string array, create a table

Basically, when given a list of strings,
I want to create a table with select statement.
For example,
"A", "B", "C",
I want to create a table as a sub-select like:
sub-select
+---------+
| "A" |
+---------+
| "B" |
+---------+
| "C" |
+---------+
How do I do this in redshift and postgres?
Thanks!
Update:
select 'a' as A;
is sort of what I want that returns:
a
+---------+
| "a" |
+---------+
How do I have multiple rows for this column a from the query select 'a' as A;
One of the way to convert a column value to multiple rows is using split_part function and UNION.
Here is an example.
Source Table:
=> CREATE TABLE t_csv (value varchar(64));
=> INSERT INTO t_csv VALUES ('"A","B","C"');
=> INSERT INTO t_csv VALUES ('"D","E"');
=> INSERT INTO t_csv VALUES ('"F","G","H","I"');
=> SELECT * FROM t_csv;
value
-----------------
"D","E"
"A","B","C"
"F","G","H","I"
(3 rows)
Here is the query to get multiple rows.
=> WITH a AS (SELECT value FROM t_csv)
SELECT * FROM
(
SELECT split_part(a.value,',',1) AS value FROM a
UNION
SELECT split_part(a.value,',',2) AS value FROM a
UNION
SELECT split_part(a.value,',',3) AS value FROM a
UNION
SELECT split_part(a.value,',',4) AS value FROM a
)
WHERE value != '';
value
-------
"A"
"B"
"C"
"D"
"E"
"F"
"G"
"H"
"I"
(9 rows)
Have no chance to test it in db, but something like that
select * INTO table from (
SELECT CAST('A' AS VARCHAR(100)) AS col
UNION ALL
SELECT 'B' AS col
UNION ALL
SELECT 'C' AS col
) a
You can use string_to_array and unnest
select *
from unnest(string_to_array('"A","B","C"', ','))
(But I don't know if that is available in Redshift)