How to concatenate multiple columns where value may be be NULL - sql

I need to pull a query from multiple columns from a table. Some rows will have data in one column, others will have two, three, and even four.
I tried to use this construct:
SELECT person_uid,('(' || major || NVL((',' ||second_major), '') || NVL((',' ||third_major), '') || NVL(',' ||fourth_major, '') || ')' ) AS MAJORS FROM academic_study
But the result would be like this:
6231 (BUMG,BUMK,,)
19091 (TDST,TDPG,,)
I need the parentheses, but not the trailing commas.
I could potentially strip out the extra commas in post processing, but I would prefer to do it in the SQL. I am using ORACLE.

You should fix your data model! Storing multiple columns with parallel data is awkward.
One method is:
select person_uid,
( '(' || major ||
(case when second_major is not null then ',' || second_major end) ||
(case when third_major is not null then ',' || third_major end) ||
(case when fourth_major is not null then ',' || fourth_major end) ||
')'
)

Related

How can combine the values of multiple columns to a single comma separated column in Oracle SQL?

I need to create a column that has all the values from the previous columns combined and separated using commas ', '
I can't use listagg since I'm trying to combine multiple columns instead of rows.
below is an example of how the result column should look like, thanks.
Use string concatenation:
select trim(leading ',' from
(case when column1 is not null then ',' || column1 end) ||
(case when column2 is not null then ',' || column2 end) ||
(case when column3 is not null then ',' || column3 end)
)
This is also using a string concatenation but slightly different
SELECT
SUBSTR(
REPLACE(
', ' || NVL(column1,'!!') || ', ' || NVL(column2,'!!') || ', ' || NVL(column3,'!!')
,', !!','')
,3,100)

comma separated list oracle sql

I have a list of comma separated values in a single field and need to find all rows which meet a certain criteria. The code I am using is:
select * from table where column_name in
(
select regexp_substr('A+','A-','aabn','[^,]+', 1,level) from table
connect by regexp_substr('A+','A-','aabn', '[^,]+', 1,level) is not null
);
so I want to find all the rows which contain A+, A- and aabn
Why not just use a single regular expression?
where regexp_like(column_name, '(^|,)(A[+]|A[-]|aabn)($|,)')
Here is a DB<>fiddle.
Also, as powerful as regular expressions are, you should not be storing multiple values in a single string. Oracle has many other options for storing multiple values, including the traditional association/junction table.
You don't need regular expressions, just use LIKE to check that the value you require is a sub-string of the column (both surrounded by delimiter characters):
If you want all 3 in the list then use AND:
SELECT *
FROM table_name
WHERE ',' || column_name || ',' LIKE '%,A+,%'
AND ',' || column_name || ',' LIKE '%,A-,%'
AND ',' || column_name || ',' LIKE '%,aabn,%'
If you want any 1 in the list then use OR:
SELECT *
FROM table_name
WHERE ',' || column_name || ',' LIKE '%,A+,%'
OR ',' || column_name || ',' LIKE '%,A-,%'
OR ',' || column_name || ',' LIKE '%,aabn,%'

Combining a CASE WHEN statement & a column containing strings of type "Column 1 || '_' || Column 2" in Oracle SQL

I have a table consisting of three columns, which are called the following:
1) Month
2) Store_Type
3) City
I need this table to be expanded to contain five columns and the two columns that I wish to be added are detailed below.
Firstly, the query needs to create a new column called Store_Code. The Store_Code columns job is to store a numerical value which corresponds to what type of store it is.
I presume this would done using a CASE WHEN statement of the type:
SELECT Month,Store_Type,City,
CASE
WHEN Store_Type = 'Corner Shop' THEN '1'
WHEN Store_Type = 'Megastore' THEN '2'
WHEN Store_Type = 'Petrol Station' THEN '3'
....
ELSE '10'
END Store_Code
FROM My_Table
After this is complete, I need to create a column known as "Store_Key". The values contained within the Store_Key column need to be of the following form:
"The Month For That Row""The Store Type For That Row""The City associated with that row"_"The Store Code for that row"
I imagine the best way to create this column would be to use a query similar to the following:
SELECT (My_Table.Month || '_' || My_Table.Store_Type || '_' || My_Table.City || '_' ||
My_Table.Store_Code)
FROM My_Table
What I need is for these two separate queries to be combined into one query. I imagine this could be done by sub-setting the different SELECT queries but I am open to and grateful for any alternative solutions.
Thank you for taking the time to read through this problem and all solutions are greatly appreciated.
Do the case expression part inside a derived table (the subquery):
SELECT (My_Table2.Month || '_' || My_Table2.Store_Type || '_' || My_Table2.City || '_' ||
My_Table2.Store_Code)
FROM
(
SELECT Month,Store_Type,City,
CASE
WHEN Store_Type = 'Corner Shop' THEN '1'
WHEN Store_Type = 'Megastore' THEN '2'
WHEN Store_Type = 'Petrol Station' THEN '3'
....
ELSE '10'
END Store_Code
FROM My_Table
) My_Table2
If this is you trying to populate your new columns, then you need an update statement. I would use two updates to ensure you get the store_case committed for your store_code. Otherwise if you're deriving it in real time, the subquery select answer would be the way to go.
update my_table
set store_case =
case store_type
when 'Corner Shop' then 1
when 'Megastore' THEN 2
when 'Petrol Station' THEN 3
...
else 10
end case;
commit;
update my_table
set store_code = Month || '_' || to_char(Store_Type) || '_' || City || '_' || Store_Code;
commit;
Why to use sub query? It can be done within single query as following:
SELECT My_Table.Month || '_' || My_Table.Store_Type || '_' || My_Table.City || '_' ||
CASE
WHEN Store_Type = 'Corner Shop' THEN '1'
WHEN Store_Type = 'Megastore' THEN '2'
WHEN Store_Type = 'Petrol Station' THEN '3'
....
ELSE '10'
END as result
FROM My_Table
or you can use DECODE function as following:
SELECT My_Table.Month || '_' || My_Table.Store_Type || '_' || My_Table.City || '_' ||
DECODE(Store_Type,
'Corner Shop', '1',
'Megastore', '2',
'Petrol Station', '3'
....,
'10') -- this is default value same as else part of the case statement
as result
FROM My_Table
Cheers!!

Oracle 12c Concatenate with brackets where nulls are involved

We have a set of columns within a table we need to concatenate, and we need brackets around the third, fourth, fifth and sixth value, but also need nothing to appear if the column is null.
SELECT "ID",
NVL(PART || '.'|| SECTION ||'(' ||SUB1||')'|| '(' ||SUB2|| ')' || '('||SUB3||')' || '('||SUB4||')', '') as concatenated
FROM table1;
Places the values exactly right as long as there are values. When any one or more columns return null, we are getting an empty set of brackets for each null value.
Such as: 113.203()()()() when there are four null values
in this case we would need: 113.203
Or 113.450(h)(2)(iv)() when there is one null value.
here the desired results
would be 113.450(h)(2)(iv)
How can I change the script to leave out all the empty brackets when a null value is returned?
Thank you.
Hmmm, I think you want:
select id,
(part || '.' || section ||
(case when sub1 is not null then '(' || sub1 || ')' end) ||
(case when sub2 is not null then '(' || sub2 || ')' end) ||
(case when sub3 is not null then '(' || sub3 || ')' end) ||
(case when sub4 is not null then '(' || sub4 || ')' end)
) as concatenated
from table1;

IN clause not working in oracle

I have a query which uses IN clause and it is not working for below case:
Select *
from table1
where
Rollno || '/' || UserId IN ('1/001,2/002')
It is not working because you haven't wrapped each value in single quotes ' :
SELECT *
FROM table1
WHERE Rollno || '/' || UserId IN ('1/001','2/002')
Notulysses has the right syntax for in. But, if you have to deal with a string, you can rephrase this as like:
where ',' || Rollno || '/' || UserId || ',' like '%,' || '1/001,2/002' || ',%'
like is a better approach. Sometimes in the real world, you might have to deal with comma-delimited strings.