Oracle SQL - Is there a better way to concatenate multiple strings with a given delimiter? - sql

First question, so apologies in advance if this is stupid or unoriginal, but I've searched for about 30 mins now without finding any mention anywhere of my exact question:
Is there a way to concatenate a series of strings, to be separated by a given delimiter, without manually putting the delimiter between each column being concatenated?
To give a concrete example, I currently have this:
SELECT member_no as Member#,
(member_gname
|| ' '
|| member_fname) as Name,
(member_street
|| ' '
|| member_city
|| ' '
|| member_state
|| ' '
|| member_postcode) AS Address,
member_phone AS Phone,
TO_CHAR(member_joindate, 'dd-Mon-yyyy') as Joined
FROM MEMBER;
It works fine, and produces exactly the output I wanted, but as this is for study I'm less concerned about the output and more concerned with the readability and 'best practise' factors of the .sql file itself. I understand that CONCAT() only takes two arguments, so that won't work without nesting them (which is even uglier and less readable). I'm coming in totally naively here, but I was hoping there'd be some kind of magical AWESOMECONCAT() type of function that would take all the columns i need, as well as allowing me to specify what character I want separating them (in this case, a space). Any ideas?
Also, this is a separate question not worthy of posting by itself, but is there any way to select a column 'AS' and give it a name including whitespace? E.g 'Member #' would look better imo, and 'Join Date' would be clearer, but I've tried both brackets and single quotes after the AS and neither seems to fly with SQL developer.

We can still write our own AWESOMECONCAT(). Unfortunately, Oracle has no in built function. As the concatenate operator does the basic thing.
Using double quotes in the alias, you can make the column references case sensitive and even accept blanks. But note that, any more references to that column/expression needs double quotes with same text.
SELECT member_no as "Member #",
(member_gname
|| ' '
|| member_fname) as Name,
(member_street
|| ' '
|| member_city
|| ' '
|| member_state
|| ' '
|| member_postcode) AS Address,
member_phone AS Phone,
TO_CHAR(member_joindate, 'dd-Mon-yyyy') as "Join Date"
FROM MEMBER;

Is there a way to concatenate a series of strings, to be separated by a given delimiter, without manually putting the delimiter between each column being concatenated?
The best way to do concatenation from 11g onwards is the new string literal technique q'[]'.
For example :
select q'[This is a string, 'this is also a string'.]' from dual

Related

Escape single quote in redshift sql in a column value

As per the attached image the column tlist in a table 'c' has values separated by a comma such as 'HCC19','HCC18'.
I am trying to used the column values in a query condition on redshift ..
where a.risk_factor in (c.tlist)
.. ..but its not giving the expected result possibly because its taking the value a single string as '
where a.risk_factor in( ' 'HCC19','HCC18' ') and not as required in the expression where a.risk_factor in('HCC19','HCC18')
Is there any workaround possible for this situation ?
You may try using a LIKE comparison here:
WHERE c.tlist LIKE '%''' || a.risk_factor || '''%';
The above LIKE expression compares 'HCC19','HCC18' searching for the single quoted risk factor. If the risk factor already comes with single quotes, then just use:
WHERE c.tlist LIKE '%' || a.risk_factor || '%';

SQLite - remove all spaces

Is there any way to remove all spaces using SQLite, kind of global trim(), not using any scripting language? I'm trying to hash values from multiple columns to track any changes but that will require to remove spaces for columns with multiple strings.
So far I wasn't able to find any tip related to that topic.
SQLite has some built-in string functions, including trim().
select trim(mycolumn) from mytable;
If you're trying to delete all spaces, you can use replace().
select replace(mycolumn, ' ', '') from mytable;
If you are trying to combine several columns you can use this with the concatenate operator.
select trim(col1) || trim(col2) || trim(col3) from mytable;
if you mean remove extra spaces
trim(replace(replace(replace(mycolumn, ' ', '| '), ' |',''), '|',''))

Full Text Search Using Multiple Partial Words

I have a sql server database that has medical descriptions in it. I've created a full text index on it, but I'm still figuring out how this works.
The easiest example to give is if there is a description of Hypertensive heart disease
Now they would like to be able to type hyp hea as a search term and have it return that.
So from what I've read it seems like my query needs to be something like
DECLARE #Term VARCHAR(100)
SET #Term = 'NEAR(''Hyper*'',''hea*'')'
SELECT * FROM Icd10Codes WHERE CONTAINS(Description, #Term)
If I take the wild card out for Hypertensive and heart, and type out the full words it works, but adding the wild card in returns nothing.
If it makes any difference I'm using Sql Server 2017
So it was a weird syntax issue that didn't cause an error, but stopped the search from working.
I changed it to
SELECT * FROM Icd10Codes where CONTAINS(description, '"hyper*" NEAR "hea*"')
The key here being I needed double quotes " and not to single quotes. I assumed it was two single quotes, the first to escape the second, but it was actually double quotes. The above query returns the results exactly as expected.
this will work:
SELECT * FROM Icd10Codes where SOUNDEX(description)=soundex('Hyp');
SELECT * FROM Icd10Codes where DIFFERENCE(description,'hyp hea')>=2;
You could try a like statement. You can find a thorough explanation here.
Like so:
SELECT * FROM Icd10Codes WHERE Icd10Codes LIKE '%hyp hea%';
And then instead of putting the String in there just use a variable.
If you need to search for separated partial words, as in an array of search terms, it gets a bit tricky, since you need to dynamically build the SQL statement.
MSSQL provides a few features for full text search. You can find those here. One of them is the CONTAINS keyword:
SELECT column FROM table WHERE CONTAINS (column , 'string1 string2 string3');
For me - this had more mileage.
create a calculated row with fields as full text search.
fullname / company / lastname all searchable.
ALTER TABLE profiles ADD COLUMN fts tsvector generated always as (to_tsvector('english', coalesce(profiles.company, '') || ' ' || coalesce(profiles.broker, '') || ' ' || coalesce(profiles.firstname, '') || ' ' || coalesce(profiles.lastname, '') || ' ' )) stored;
let { data, error } = await supabase.from('profiles')
.select()
.textSearch('fts',str)

search for the presence of two strings in oracle database in a clob column?

I have a clob column with a long string.
like "great job done today. good "
I want to retrieve all the records which has both the words great and good .
both the position is not fixed.
It's not clear what "which has both the words great and good " actually means.
If you mean you want to check if the string has both patterns of words, then it is simple as
where lower(col) like '%good%' AND lower(col) like '%great%'
If you mean they should contain true words good and great, then for simpler cases something like should do
where ' ' || lower(col) || ' ' LIKE '% good %' AND ' ' || lower(col) || ' ' LIKE '% great %'
However, this will not match a sentence ending with the word and having a full stop. It gets lengthy if you want to simply use LIKE to handle such scenarios.
REGEXP functions give more flexibility, but could be less performant.
WHERE REGEXP_LIKE ( s, '(^|\W)good(\W|$|\.)') AND REGEXP_LIKE ( s, '(^|\W)great(\W|$|\.)')
This searches for word boundaries, i.e. the word surrounded by non-word characters and start and end including an ending dot. If you want to ignore case, add ,'i' as 3rd argument to it.
I think this is the basic logic you want:
where lower(col) like '%good%' and lower(col) like '%great%'
In clobs, you can't quite use like:
where dbms_lob.instr(col, 'good') and dbms_log.instr(col, 'great')
Try this and let me know if it works for you.
SELECT *
FROM clob_table
WHERE DBMS_LOB.INSTR(clob_text,'great')>0
AND DBMS_LOB.INSTR(clob_text,'good')>0;
Remember put the names of your table and columns.
Here my results,

How to replace common words in sql column

I have a table of common words that are used in sentences (i.e. A, the, and, where, etc...)
What I want to do is loop through all those words and strip them out of the descriptions that people have entered to attempt to generate common keywords or tags. But I can't use replace because replace will remove any instance of the common word regardless of whether it is only a couple of letters that make up a larger word. For instance:
I want to replace A in the description. Now obviously a lot of words contain the letter a. So all those A's will be stripped from the words. I don't want that. I only want it when A is used a a whole word. I can figure this out using regular expressions but was wondering if there was anyway to do this in SQL without having to resort to CLR proc.
Maybe I am missing something but I couldn't seem to find an easy way to do this without having to write some specific scenarios like: word plus space before, word plus space after, word plus period after, etc... I don't think that is the best way.
For quick and dirty, I used to slosh through the various SQL functions PATINDEX, LEFT, RIGHT and LIKE to do this sort of thing. For one-time data prep, I export to something like Excel and eyeball it.
A good approach also is to create a new StringSubstitutionTable with two columns SOURCESTRING and TARGETSTRING and run a replace function to replace the SOURCESTRING with the TARGETSTRING on the joined table. This is cool because you can just add substitution entries as needed.
You can try nesting the replaces for each word you would like to replace. For example:
UPDATE TableName
SET ColumnName = REPLACE(REPLACE(REPLACE(REPLACE(TableName.ColumnName,' a ',' '),' the ',' '),' and ',' '), ' ', ' ')
Let me know if this is what you were looking for.
Here is they way I did something similar to what you are trying to do.
During your replace action...
Append a space before and after the common word.
Append a space before and after the description.
Let's suppose you want to remove the CommonWord "A" from the Description.
Description: "A good phrase never starts with A or ends with A"
CommonWord: "A"
Update TableName
Set Description =
LTRIM(RTRIM(Replace(' ' + Description + ' ', ' ' + CommonWord + ' ', ' ')))
This lets you delete all whole words that equal 'A'. Because you are replacing ' A ' with a space you need to LTRIM RTRIM to remove any leading or trailing spaces.
You could also do this in two steps:
--
-- Step 1 Loop through all common words removing them
--
Update TableName
Set Description = Replace(' ' + Description + ' ', ' ' + CommonWord + ' ', ' ')
--
-- Step 2 Unconditionally Trim all Descriptions
--
Update TableName
Set Description = LTRIM(RTIM(Description))