split up sql column into queryable results set - sql

Here is my issue:
I have a column with the following data in an sql column:
Answers
=======
1:2:5: <--- notice my delimiter
I need to be able to break up the digits into a result set that i can join against a lookup table such as
Answers_Expanded
=======
1 apple
2 pear
3 cherry
4 mango
5 grape
and return
Answers
=======
apple pear grape
Any such way?
Thanks!

This is a bit of a hack (the LIKE, the XML PATH, and the STUFF), and it assumes that you want the answers ordered by their ID as opposed to matching up with the original order in the multivalued column...
But this gives the results you're looking for:
SELECT STUFF((
SELECT ' ' + ae.Answer
FROM
Answers_Expanded ae
JOIN Answers a ON ':' + a.Answers LIKE '%:' + CAST(ae.ID AS VARCHAR) + ':%'
ORDER BY ae.ID
FOR XML PATH(''))
, 1, 1, '') AS Answers
Sql Fiddle
This works because:
Joining with LIKE finds any Answer_Expanded rows that match the multivalued column.
XML PATH simulates a group concatenation... and allows for ' ' to be specified as the delimiter
STUFF removes the leading delimiter.

This blog post has a good example of a user defined function that will return a table with the values from your delimited string in a column. You can then join that table to your Answers_Expanded table to get your value.
This works fine if you are parsing reasonably short strings, and if you are doing it as a one time thing, but if you have a table with your answers stored in a column like that, you don't want to be running this on the whole table as it will be a large performance hit. Ideally you'd want to avoid getting delimited strings like this in SQL.

i would suggest that you save your answers in a way that one cell has only one number...not multible information in one cell. (violation of the 1st normal form).
otherwise you better use some higher sql language such as T-SQL.

Related

BigQuery: Call a UDF on each column of each row and aggregate the output in new column dynamically

I have come up with a JS UDF in BigQuery which needs to be call on each cell of each row and the output of that row needs to be aggregated in another column dynamically & should work for all tables. I have referred answer provided by Mikhail in this question : BigQuery - Concatenate multiple columns into a single column for large numbers of columns
This answer partially works for me. But since, some of my tables have columns having text with comma, it ends up in splitting those columns again. eg. In below screenshot, it should have 5 values in the last column one for each. I have tried few ways like using %T for format etc. since I need to make it generic. It is having limitations.by comma.
Following is the query I am using :
SELECT *, (SELECT string_agg(myFunc(col), ', ' ORDER BY offset) FROM UNNEST(split(trim(format('%t', (SELECT AS struct t.* )), '()'), ', ')) col WITH offset WHERE NOT upper(col) = 'NULL') AS funcOutPut FROM `my-project`.db.customer t;
Is there anyway this can be achieved generically for all the tables I have? Any help would be appreciated. :)

Big Query Record split into multiple columns

I have a table that looks like:
text | STRING
concepts | RECORD
concepts.name | STRING
[...]
So one row could look like this:
"This is a text about BigQuery and how to split records into columns. "
SQL
BigQuery
Questions
I would like to transform that into:
text, concepts_1, concepts_2, concepts_3 // The names are not important
"This is a text about BigQuery and how to split records into columns. ",SQL,BigQuery,Questions
The number of concepts in each row vary.
EDIT:
This would also work:
text, concepts
"This is a text about BigQuery and how to split records into columns. ","SQL,BigQuery,Questions"
Below is for BigQuery Standard SQL
If comma separated list is fine with you - consider below shortcut versions
#standardSQL
SELECT identifier,
(SELECT STRING_AGG(name, ', ') FROM UNNEST(concepts)) AS conceptName
FROM `project.dataset.articles`
and
#standardSQL
SELECT identifier,
(SELECT STRING_AGG(name, ', ') FROM articles.concepts) AS conceptName
FROM `project.dataset.articles` articles
Both above versions return output like below
Row identifier conceptName
1 1 SQL, BigQuery, Questions
2 2 xxx, yyy, zzz
As you can see - above versions are brief and compact and don't use extra grouping to array with then transforming it into string - as all this can be done in one simple shot
This was the solution for me. But it only creates a comma-separated string. However, in my case, this was fine.
SELECT articles.identifier, ARRAY_TO_STRING(ARRAY_AGG(concepts.name), ",") as
conceptName
FROM `` articles, UNNEST(concepts) concepts
GROUP BY articles.identifier
Try using this:
SELECT
text,
c.*
FROM
`your_project.your_dataset.your_table`,
UNNEST(
concepts
) c
This will get the text column along with the unnested values from your RECORD column.
Hope it helps.

How to combine the multiple lines of data of a single column of data base into one line while retrieving or after retrieving. I am using JDBC

How to combine the multiple lines of data of a single column of data base into one line while retrieving or after retrieving. I am using JDBC to retrieve the data.
Below is example
Column address is stored as below in database and when retrieved and populated in Excel also it is populated in different rows of the column (different cells)
plot-22, xyz
Bangalore
Karnataka
521638
after retrieving the data from data base I have to put it in a excel file as below in one cell
plot-22, xyz Bangalore Karnataka 521638
I have tried many ways but not able remove the escape line and combine into one line.
I am using SQL Server database.
You can use STUFF function, it's a bit tricky and you have to care about the order in which you have to put all the records that form the address. Something like this can work:
declare #addr varchar(MAX)
SET #addr = STUFF( (SELECT ',' + [Address] FROM Table_1 WHERE Cust_ID = 1
ORDER BY sub_id FOR XML PATH('') ), 1, 1, '')
print #dir
This thread is very useful to understand how stuff works:
How Stuff and 'For Xml Path' work in Sql Server
Your answer will be easy like:
A PIVOT used to rotate the data from one column into multiple columns
https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot
I have got the solution. We need to append double quote (")to the string to remove next line character
{
String values = rs.getString(j);
char ch = '"';
String nvalues = ch + values + ch; // To escape the next line character
}

Pass multiple values in Syabse

I am back again with a small problem. Hope i get something here.
I am working on a report, SQL Server Reporting Services 2012 and Database is Sybase ASE.
One of my report parameter can have multiple values. Let's name the parameter as #Fruit. It can have multiple values. So if the user selects Apple and Mango from the list, it should pass to the query at backend.
The parameter gives the values as : Apple,Mango
Now i need to pass it to the query in the below way.
SELECT
COLUMN1,
COLUMN2,
COLUMN3
FROM DBO.TABLE_NAME
WHERE COLUMN2 IN ('Apple','Mango')
Problem: I am able to pass a single fruit name at a time. But not able to pass more than one value. I did a bit research and found it's problem with Sybase. It cannot take multiple value.
I believe someone might have found a work around. Just need to get it working.
Thanks In Advance.!
you can create a comma separated string from the list using join in a expression:
strFruits= Join(Parameters!fruits.Value,",")
then your where clause would look like:
WHERE CHARINDEX(',' + COLUMN2 + ',' , ',' + #strFruits + ',')>0
the ',' added at the beginning and end of the strings are to make sure the search string is found even if it is located at beginning or end of the comma separated list.

SQlite query to update column and replace a value

I want to update a column that contains a string like 12,43,433 I want to only replace 43 with another number say 54 so that the column value becomes 12,54,433.
How can I do that??
You can use REPLACE() function like this:
UPDATE YourTable a
SET a.StringColumn = REPLACE(a.StringColumn,',43,',',54,')
WHERE a.StringColumn like '%,43,%'
Storing lists as strings is a very bad idea. SQL has a great data structure for storing lists. It is called a table, not a string. The proper way to store lists is to use a junction table.
Sometimes we are stuck with other people's really bad design decisions. If so, you can do:
update t
set col = trim(replace(',' || col || ',', ',43,', ',54,'), ',')
where ',' || col || ',' like '%,43,%';
Notes:
This works regardless of where the "43" appears in the string (including at the beginning and end).
This maintains the format of the string with no commas at the beginning and end.
This only attempts to update rows that have the particular elements in the list.
Use of such a query should really be a stopgap while you figure out how to fix the data structure.