that will sounds stupid, but I have a table with names, those names may finish with white space or may not. E.g. I have name ' dummy ', but even if in the query I write only ' dummy' it will find the record ' dummy '. Can I fix it somehow?
SELECT *
FROM MYTABLE where NAME=' dummy'
Thanks
This is how SQL works (except Oracle), when you compare two strings the shorter one will be padded with blanks to the length of th 2nd string.
If you really need to consider trailings blanks you can switch to LIKE which doesn't follow that rule:
SELECT *
FROM MYTABLE where NAME LIKE ' dummy'
Of course, you better clean your data during load.
There's only one thing which is worse than trailing spaces, leading spaces (oh, wait a minute, you got them, too).
Related
I am looking for some help in regards to removing trailing spaces from my queue names. The following is an example of a table that I am using:
QUEUE_NAME
Queue A
Queue B
Queue C
The problem I have is that there is an extra space at the end of the queue name and when trying the following code:
SELECT
TRIM(TRAILING ' ' FROM QUEUE_NAME)
FROM
TABLE_QUEUE;
the space is still there.
I was reading the searches from Google and came across the following code to remove special characters [https://community.oracle.com/blogs/bbrumm/2016/12/11/how-to-replace-special-characters-in-oracle-sql] and this removed all the spaces including the one at the end. The code I wrote:
SELECT
REGEXP_REPLACE(QUEUE_NAME, '[^0-9A-Za-z]', '')
FROM
TABLE_QUEUE;
Only issue I have now is that my result is shown as the following:
QUEUE_NAME
QueueA
QueueB
QueueC
I have never really used regexp_replace hence not sure what I need to change to the code to leave the spaces in between the queue names, so would really appreciate it if somebody could advise on how I could fix this.
Thanks in advance.
---- code edited as should not include [.!?]+
You may try to use trim only as in the following select statement :
with t(col0) as
(
select ' Queue A ' from dual union all
select ' Queue B ' from dual union all
select ' Queue C ' from dual
)
select trim(col0)
from t;
trimmedText
-----------
Queue A
Queue B
Queue C
you get no surrounding spaces around.
You want to remove space from the end of the string:
regexp_replace(queue_name, '[[:space:]]+$', '')
(The '$' in the pattern marks the end.)
If this still doesn't work, then you are dealing with some strange invisible character that is not considered space. Use
regexp_replace(queue_name, '[^0-9A-Za-z]+$', '')
instead, which, as you already know, removes all characters except for letters and digits. The '$' restricts this to the end of the string.
Columns of type CHAR (e.g. CHAR(8)) are always blank-padded on the right to the full width of the field. So if you store 'Queue A' in a CHAR(8) field the database helpfully adds a single space to the end of it - and there's no way to remove that extra space from the column. The solution is to change the field so it's defined as either VARCHAR2 (preferred in Oracle) or VARCHAR:
ALTER TABLE TABLE_QUEUE MODIFY QUEUE_NAME VARCHAR2(8);
Then the database will only store the characters you give it, without blank-padding the field.
Best of luck.
I don't recall ever seeing a field like this before, but it combines the city, state, and zipcode into a single string of varchar2. Fortunately, I believe most of the fields are in the same city space state, space zipcode format, but I started finding a few that deviated from that norm.
Right now I'm trying to identify all these distinct conditions
in the database with over 5 million rows and my queries aren't working for what I wanted.
I started with:
SELECT PROJECT_CTY_ST_ZIP FROM PAYMENT WHERE PROJECT_CTY_ST_ZIP LIKE '%' || CHR(32) || '%';
Then tried:
SELECT PROJECT_CTY_ST_ZIP FROM PAYMENT WHERE PROJECT_CTY_ST_ZIP LIKE '% %' AND PROJECT_CTY_ST_ZIP LIKE '% %' AND PROJECT_CTY_ST_ZIP LIKE '% %';
but they are both pulling based on leading and trailing spaces and I was really wanted to find spaces in the inside of the text. I don't want to remove them, just identify them with a query so I can parse them properly in my java code and then do an insert later to put them into city, state, and zipcode fields in another table.
While it doesn't show it here, I found this field in IA with no leading spaces, then one leading space and then two leading spaces. I fixed the leading spaces with trim.
WEST LIBERTY, IA 52776
This last one I wasn't expecting and I wanted to see if there are other conditions that might be unusual, but my query doesn't find them as the spaces are in the middle of the text:
TRUTH OR CONSEQUENCE, NM 87901
How would I go about a query to find these kinds of distinct records?
This query replaces each of the spaces with a dot (.) so you can see them
SELECT
REGEXP_REPLACE(PROJECT_CTY_ST_ZIP,
'([[:space:]])',
'.') spaces_or_now_dots
FROM PAYMENT
This query finds the ones that have one or more spaces.
SELECT PROJECT_CTY_ST_ZIP
FROM PAYMENT
where REGEXP_LIKE(PROJECT_CTY_ST_ZIP,
'[[:space:]]'
)
I have not considered the cases of spaces in the beginning and end, because you have already taken care of them.
I would like to ask for advice on records testing.
At this point, I have an account field that must consist of numbers only. Nevertheless, this is a varchar field because of the leading zeroes.
I had this query that actually shows me non-digits in the account number (or null).
LTRIM(TRANSLATE(ACCOUNT,'0123456789',' '),' ') INVALID_DATA
Nevertheless, I just faced another issue- spaces are not taken into account, and therefore if account has a space, it goes unnoticed as null. Yes, I can replace space with something more recognizable, but will it be enough? I am sure there are other exceptions I don't know about.
Is there any universal way to check for ANY POSSIBLE variation that is not a number? maybe something like this? How reliable is it?
LENGTH(ACCOUNT)-LENGTH(TO_NUMBER(REGEXP_REPLACE((ACCOUNT), '[^[:digit:]]+', ''))) NON-NUMBERS
Also, how to detect and account for cases with non-Unicode characters?
I would just use a regexp_replace approach to find non-numbers in a string:
regexp_replace(account, '\d+')
Explanation
-The escape character, \d, is metacharacter for a digit character.
-The + symbol is a quantifier indicating one or more instances of this digit.
Thus, we are removing all digits from the account column and where this is non-null,
you have non-number left.
~~~~~~~~~~~~
With respect to your calculation:
LENGTH(ACCOUNT)-LENGTH(TO_NUMBER(REGEXP_REPLACE((ACCOUNT), '[^[:digit:]]+', ''))) NON-NUMBERS
Your reg expression looks for non-digits and removes them. Your approach will work (I do not like converting the string to a number then dynamically casting as a string). If you use this in a condition, it would need to be encapsulated in a NVL function like this:
NVL(LENGTH(ACCOUNT)-LENGTH(REGEXP_REPLACE(ACCOUNT, '[^[:digit:]]+', '')),0) NON-NUMBERS
I think you have the right idea:
LTRIM(TRANSLATE(ACCOUNT, ' 0123456789', 'X'), ' ') as INVALID_DATA
Should return a non-empty string when there is a space.
In a where clause you would use:
where LENGTH( LTRIM(TRANSLATE(ACCOUNT, ' 0123456789', 'X'), ' ')) > 0
You can replace all spaces like this:
SELECT REPLACE(fld_or_variable, ' ', '')
Or you can trim spaces like this
SELECT LTRIM(RTRIM(' Amit Tech Corp '))
I'm trying to select some rows from an Oracle database like so:
select * from water_level where bore_id in ('85570', '112205','6011','SP068253');
This used to work fine but a recent update has meant that bore_id in water_level has had a bunch of whitespace added to the end for each row. So instead of '6011' it is now '6011 '. The number of space characters added to the end varies from 5 to 11.
Is there a way to edit my query to capture the bore_id in my list, taking account that trialling whitespace should be ignored?
I tried:
select * from water_level where bore_id in ('85570%', '112205%','6011%','SP068253%');
which returns more rows than I want, and
select * from water_level where bore_id in ('85570\s*', '112205\s*','6011\s*', 'SP068253\s*');
which didn't return anything?
Thanks
JP
You should RTRIM the WHERE clause
select * from water_level where RTRIM(bore_id) in ('85570', '112205','6011');
To add to that, RTRIM has an overload which you can pass a second parameter of what to trim, so if the trailing characters weren't spaces, you could remove them. For example if the data looked like 85570xxx, you could use:
select * from water_level where RTRIM(bore_id, 'x') IN ('85570','112205', '6011');
You could use the replace function to remove the spaces
select * from water_level where replace(bore_id, ' ', '') in ('85570', '112205', '6011', 'SP068253');
Although, a better option would be to remove the spaces from the data if they are not supposed to be there or create a view.
I'm guessing bore_id is VARCHAR or VARCHAR2. If it were CHAR, Oracle would use (SQL-standard) blank-padded comparison semantics, which regards 'foo' and 'foo ' as equivalent.
So, another approach is to force comparison as CHARs:
SELECT *
FROM water_level
WHERE CAST(bore_id AS CHAR(16)) IN ('85570', '112205', '6011', 'SP068253');
My wording may not be correct so the solution could be on this site. In which case, pointing me to the solution would be great. Anyway, I am doing a search and need to do compares against the string and value that is in a column. It has to go beyond LIKE. For instance, I want to take the column put it in lower case and take out all spaces before comparing it to the string (which is too put in lower case and all spaces are gone). I want to do this without modifying the contents of the column. So just for the compare. Then if the compare evaluates to true take the original contents out of the column (not in the lower case and no spaces form). This may be to specific. Is it possible to do this, if so, any code sample would help. So I have something like this now:
SELECT *
FROM [MY_TABLE]
WHERE (
[MY_COLUMN] LIKE My_Search_String
)
so the My_Search_String is already formatted. I just need to format the [MY_COLUMN] without permanently modifying its contents. Any help is appreciated. Thank you!
Upper and lower case only make a difference if your default collations or column collations are case sensitive. In any case, you seem to want:
SELECT *
FROM [MY_TABLE]
WHERE lower(replace([MY_COLUMN], ' ', '')) LIKE lower(replace(My_Search_String, ' ', ''))
I think below query will solve your problem.!
IF EXISTS(select * from [MY_TABLE] where LOWER(REPLACE([MY_COLUMN],' ','')) like 'My_Search_String')
INSERT INTO Another_Table
select * from [MY_TABLE] where LOWER(REPLACE([MY_COLUMN],' ','')) like 'My_Search_String'