SAP HANA SQL - Concatenate multiple result rows for a single column into a single row - sql

I am pulling data and when I pull in the text field my results for the "distinct ID" are sometimes being duplicated when there are multiple results for that ID. Is there a way to concatenate the results into a single column/row rather than having them duplicated?
It looks like there are ways in other SQL platforms but I have not been able to find something that works in HANA.
Example
Select
Distinct ID
From Table1
If I pull only Distinct ID I get the following:
ID
1
2
3
4
However when I pull the following:
Example
Select
Distinct ID,Text
From Table1
I get something like
ID
Text
1
Dog
2
Cat
2
Dog
3
Fish
4
Bird
4
Horse
I am trying to Concat the Text field when there is more than 1 row for each ID.
What I need the results to be (Having a "break" between results so that they are on separate lines would be even better but at least a "," would work):
ID
Text
1
Dog
2
Cat,Dog
3
Fish
4
Bird,Horse

I see Kiran has just referred to another valid answer in the comment, but in your example this would work.
SELECT ID, STRING_AGG(Text, ',')
FROM TABLE1
GROUP BY ID;
You can replace the ',' with other characters, maybe a '\n' for a line break
I would caution against the approach to concatenate rows in this way, unless you know your data well. There is no effective limit to the rows and length of the string that you will generate, but HANA will have a limit on string length, so consider that.

Related

HANA concat rows

I use SAP-HANA database. I have a simple 2 column table whose columns are number, name, noodles, fish . The rows are these:
number name noodles fish
1 tom x
1 tom x
1 jack
2 jack x
I would like to group the rows by the id, and concatenate the names into a field, and thus obtain this:
number name noodles fish
1 tom x x
2 jack x
Can you please tell me how we can perform this operation in sap-hana? Thanks in advance.
Well, you did not really concatenate the names, but instead kept the same ones (if you would have concatenated the names as well, you would get something like jackjack in your result). I guess your x's indicate some sort of ABAP-style flags.
In any case, you would do this with grouping. This is a completely non-HANA thing (you can use the same basic SQL for any DB). You can group against several columns. All other columns that you want to select must be used in an aggregated expression (e.g. a SUM, MAX, COUNT, etc.).
To get the output from your question, I wrote the following code:
SELECT "ID", "NAME", MAX("FISH"), MAX("NOODLES")
FROM #TEST GROUP BY "ID", "NAME";
And got the same output as you. I used the MAX function based on the following assumption: you would want to get X if there is any X in the "concatenated" (aggregated) rows in that column. You get nothing / space if all the "concatenated" rows have space in them.

SQL Query - Limited by another SQL query of a different data type

I need some help on this one. I have a query that I need to make work but I need to limit it by the results of another query.
SELECT ItemID, ItemNums
FROM dbo.Tables
ItemNums is a varchar field that is used to store the strings of the various item numbers.
This produces the following.
ItemID ItemNums
1 1, 4, 5
2 1, 3, 4, 5
3 2
4 4
5 1
I have another table that has each item number as an INT that I need to use to pull all ItemIDs that have the associated ItemNums
Something like this.
SELECT *
FROM dbo.Tables
WHERE ItemNums IN (4,5)
Any help would be appreciated.
If possible, you should change your database schema. In general, it's not good to store comma delimited lists in a relational database.
However, if that's not an option, here's one way using a join with like:
select *
from dbo.Tables t
join dbo.SecondTable st on ', '+t.ItemNums+',' like '%, '+st.ItemNumId+',%'
This concatenates commas to the beginning and end of the itemnums to ensure you only match on the specific ids.
I personally would recommend normalizing your dbo.tables.
It would be better as:
ItemID ItemNums
1 1
1 4
1 5
2 1
etc.
Then you can use a join or a sub query to pull out the rows with ItemNums in some list.
Otherwise, it's going to be a mess and not very fast.

SQL list only unique / distinct values

I have a table which contains geometry lines (ways).There are lines that have a unique geometry (not repeating) and lines which have the same geometry (2,3,4 and more). I want to list only unique ones. If there are, for example, 2 lines with the same geometry I want to drop them. I tried DISTINCT but it also shows the first result from duplicated lines. I only want to see the unique ones.
I tried window function but I get similar result (I get a counter on first line from the duplicating ones). Sorry for a newbie question but I'm learning :) Thanks!
Example:
way|
1 |
1 |
2 |
3 |
3 |
4 |
Result should be:
way|
2 |
4 |
That actually worked. Thanks a lot. I also have other tags in this table for every way (name, ref and few other tags) When I add them to the query I loose the segregation.
select count(way), way, name
from planet_osm_line
group by way, name
having count(way) = 1;
Without "name" in the query I get all unique values listed but I want to keep "name" for every line. With this example I stilll get all the lines in the table listed.
To expound on #Nithila answer:
select count(way), way
from your_table
group by way
having count(way) = 1;
You first calculate the rows you want, and then search for the rest of the fields. So the aggregation doesnt cause you problems.
WITH singleRow as (
select count(way), way
from planet_osm_line
group by way
having count(way) = 1
)
SELECT P.*
FROM planet_osm_line P
JOIN singleRow S
ON P.way = S.way
you can group by way and while taking the data out check the count=1.It will give non duplicating data.
#voyteck
As I understood your question you need to get only non duplicating records of way column and for each row you need to show the name is it
If so, you have to put all the column in select statement, but no need to group by all the columns.
select count(way), way, name
from planet_osm_line
group by way
having count(way) = 1;

Searching for a number in a database column where column contains series of numbers seperated by a delimeter '"&" in SQLite

My table structure is as follows :
id category
1 1&2&3
2 18&2&1
3 11
4 1&11
5 3&1
6 1
My Question: I need a sql query which generates the result set as follows when the user searched category is 1
id category
1 1&2&3
2 18&2&1
4 1&11
5 3&1
6 1
but i am getting all the results not the expected one
I have tried regexp and like operators but no success.
select * from mytable where category like '%1%'
select * from mytable where category regexp '([.]*)(1)(.*)'
I really dont know about regexp I just found it.
so please help me out.
For matching a list item separated by &, use:
SELECT * FROM mytable WHERE '&'||category||'&' LIKE '%&1&%';
this will match entire item (ie, only 1, not 11, ...), whether it is at list beginning, middle or end.

SQL Select where id is in `column`

I have a column that has multiple numbers separated by a comma. Example for a row:
`numbers`:
1,2,6,66,4,9
I want to make a query that will select the row only if the number 6 (for example) is in the column numbers.
I cant use LIKE because if there is 66 it'll work too.
You can use like. Concatenate the field separators at the beginning and end of the list and then use like. Here is the SQL Server sytnax:
where ','+numbers+',' like '%,'+'6'+',%'
SQL Server uses + for string concatenation. Other databases use || or the concat() function.
You should change your database to rather have a new table that joins numbers with the row of your current table. So if your row looks like this:
id numbers
1 1,2,6,66,4,9
You would have a new table that joins those values like so
row_id number
1 1
1 2
1 6
1 66
1 4
1 9
Then you can search for the number 6 in the number column and get the row_id