TERADATA: Unwanted whitespaces generated while updating a row - sql

I have a table called UDB.feed_counter (feed_name VARCHAR(255), feed_counter VARCHAR(255)) which keeps track of the highest number from some other table:
when updating the number (feed_counter) I use this query:
update UDB.feed_counter from(select max(distinct LFD_NR) AS LFD_NR from DWH.ART) A SET feed_counter=A.LFD_NR where feed_name='devicecataloglocal_art';
For some reason when I update feed_counter with this query I get some whitespaces in front of a number
Why is that happening??
When I do this: select max(distinct CAST(LFD_NR AS INTEGER)) from DWH.ART; I don't get any whitespaces
Can someone explain?
Additionally I should add that LFD_NR from DWH.ART is a string containing a number.

Generally, when VARCHAR columns values are updated from CHAR column values, the targeted VARCHAR columns are populated with exactly same value as that of CHAR column value from source by removing trailing whitespaces. But no whitespaces are addded in front.
I guess, the issue is with LFD_NR column of DWH.ART table.
Try selecting values from DWH.ART without casting as INTEGER:
select max(distinct LFD_NR) from DWH.ART;
There is a chance the LFD_NR column has whitespaces in front for the values.

Related

How to remove decimal point and update without decimal for existing records?

I would like to remove the decimal point from the records and update the without decimal point which is already loaded records into the table for 4 fields
datatype: VARCHAR(7)
For example, D21.3 would become D213
All you need is a simple REPLACE function, it takes the column, whatever character or string you want to replace, and what you want to replace it with.
In this case, you want to replace any decimal points with nothing so the syntax would be:
UPDATE table_name SET column_name = REPLACE(column_name, '.','')

Oracle numeric string column and indexing

I have a numeric string column in oracle with or without leading zeros samples:
00000000056
5755
0123938784579343
00000000333
984454
The issue is that partial Search operations using like are very slow
select account_number from accounts where account_number like %57%
one solution is to restrict the search to exact match only and add an additional integer column that will represent the numeric value for exact matches.
At this point I am not sure we can add an additional column,
Do you guys have any other ideas?
Is it possible to tell Oracle to index the numeric string column as an integer value so we can do exact numeric match on it?
for example query on value :00000000333
will be:
select account_number from accounts where account_number = '333'
While ignoring the leading zeros.
I can use regex_like and ignore them, but I am afraid its going to be slow.
Oracle supports function based indexes. SO if you index the result of to_number:
CREATE INDEX acocunt_number_idx
ON accounts(TO_NUMBER(account_number))
The way, if you use a query with to_number for the exact numeric value, the index will be used:
SELECT account_number
FROM accounts
WHERE TO_NUMBER(account_number) = 333
You can use to_number.
select account_number from accounts
where to_number(account_number) = 333

Extract alphanumeric value from varchar column

I have a table which contains a column having alphanumeric values which is stored as a string. I have multiple values in that column having values such as F4737, 00Y778, PP0098, XXYYYZ etc.
I want to extract values starting with a series of F and must have numeric values in that row.
Alphanumeric column is the unique column having unique values but the rest of the columns contain duplicate values in my table.
Futhermore, once these values are extracted I would like to pick up the max value from the duplicate row,for eg:
Suppose I have F4737 and F4700 as a unique Alphanumeric row, then F4737 must be extracted from it.
I have written a query like this but the numeric values are not getting extracted from this query:
select max(Alplanumeric)
from Customers
where Alplanumeric '%[F0-9]%
or
select max(Alplanumeric)
from Customers
where Alplanumeric like '%[0-9]%'
and Alplanumeric like 'F%'**
I run the above query but I am only getting the F series if I remove the numeric part from the above query. How do I extract both, the F starting series as well as the numeric values included in that row?
Going out on a limb, you might be looking for a query like this:
SELECT *, substring(alphanumeric, '^F(\d+)')::int AS nr
FROM customers
WHERE alphanumeric ~ '^F\d+'
ORDER BY nr DESC NULLS LAST
, alphanumeric
LIMIT 1;
The WHERE conditions is a regular expression match, the expression is anchored to the start, so it can use an index. Ideally:
CREATE INDEX customers_alphanumeric_pattern_ops_idx ON customers
(alphanumeric text_pattern_ops);
This returns the one row with the highest (extracted) numeric value in alphanumeric among rows starting with 'F' followed by one ore more digits.
About the index:
PostgreSQL LIKE query performance variations
About pattern matching:
Pattern matching with LIKE, SIMILAR TO or regular expressions in PostgreSQL
Ideally, you should store the leading text and the following numeric value in separate columns to make this more efficient. You don't necessarily need more tables like has been suggested.

Alter column from varchar to decimal when nulls exist

How do I alter a sql varchar column to a decimal column when there are nulls in the data?
I thought:
ALTER TABLE table1
ALTER COLUMN data decimal(19,6)
But I just get an error, I assume because of the nulls:
Error converting data type varchar to numeric. The statement has been terminated.
So I thought to remove the nulls I could just set them to zero:
ALTER TABLE table1
ALTER COLUMN data decimal(19,6) NOT NULL DEFAULT 0
but I dont seem to have the correct syntax.
Whats the best way to convert this column?
edit
People have suggested it's not the nulls that are causing me the problem, but non-numeric data. Is there an easy way to find the non-numeric data and either disregard it, or highlight it so I can correct it.
If it were just the presence of NULLs, I would just opt for doing this before the alter column:
update table1 set data = '0' where data is null
That would ensure all nulls are gone and you could successfully convert.
However, I wouldn't be too certain of your assumption. It seems to me that your new column is perfectly capable of handling NULL values since you haven't specified not null for it.
What I'd be looking for is values that aren't NULL but also aren't something you could turn in to a real numeric value, such as what you get if you do:
insert into table1 (data) values ('paxdiablo is good-looking')
though some may argue that should be treated a 0, a false-y value :-)
The presence of non-NULL, non-numeric data seems far more likely to be causing your specific issue here.
As to how to solve that, you're going to need a where clause that can recognise whether a varchar column is a valid numeric value and, if not, change it to '0' or NULL, depending on your needs.
I'm not sure if SQL Server has regex support but, if so, that'd be the first avenue I'd investigate.
Alternatively, provided you understand the limitations (a), you could use isnumeric() with something like:
update table1 set data = NULL where isnumeric(data) = 0
This will force all non-numeric values to NULL before you try to convert the column type.
And, please, for the love of whatever deities you believe in, back up your data before attempting any of these operations.
If none of those above solutions work, it may be worth adding a brand new column and populating bit by bit. In other words set it to NULL to start with, and then find a series of updates that will copy data to this new column.
Once you're happy that all data has been copied, you should then have a series of updates you can run in a single transaction if you want to do the conversion in one fell swoop. Drop the new column and then do the whole lot in a single operation:
create new column;
perform all updates to copy data;
drop old column;
rename new column to old name.
(a) From the linked page:
ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($).
Possible solution:
CREATE TABLE test
(
data VARCHAR(100)
)
GO
INSERT INTO test VALUES ('19.01');
INSERT INTO test VALUES ('23.41');
ALTER TABLE test ADD data_new decimal(19,6)
GO
UPDATE test SET data_new = CAST(data AS decimal(19,6));
ALTER TABLE test DROP COLUMN data
GO
EXEC sp_RENAME 'test.data_new' , 'data', 'COLUMN'
As people have said, that error doesn't come from nulls, it comes from varchar values that can't be converted to decimal. Most typical reason for this I've found (after checking that the column doesn't contain any logically false values, like non-digit characters or double comma values) is when your varchar values use comma for decimal pointer, as opposed to period.
For instance, if you run the following:
DECLARE #T VARCHAR(256)
SET #T = '5,6'
SELECT #T, CAST(#T AS DEC(32,2))
You will get an error.
Instead:
DECLARE #T VARCHAR(256)
SET #T = '5,6'
-- Let's change the comma to a period
SELECT #T = REPLACE(#T,',','.')
SELECT #T, CAST(#T AS DEC(32,2)) -- Now it works!
Should be easy enough to look if your column has these cases, and run the appropriate update before your ALTER COLUMN, if this is the cause.
You could also just use a similar idea and make a regex search on the column for all values that don't match digit / digit+'.'+digit criteria, but i suck with regex so someone else can help with that. :)
Also, the american system uses weird separators like the number '123100.5', which would appear as '123,100.5', so in those cases you might want to just replace the commas with empty strings and try then?

Eliminate whitespaces in table columns

I have a scenario where I have to convert varchar column into number column. While doing that I'm getting error invalid number. After debugging the values some has whitespaces and some other values entered as 56.678.90. Below is the query I tried to convert varchar into number,
select cast('45.56.78' as number) from dual or
select cast (' ' as number) from dual
Both the values which I have entered in the above query will be there under column 'lddfc' in table entry_header. Column lddfc has records as 456.99, 456.89.43, and whitespace. How can I display these values as number?
You haven't mentioned what variant of SQL you are using but if it's T-SQL you could remove leading and trailing spaces using LTRIM(RTRIM(yourValue)). Not sure about syntax for PL/SQL.
So your code would be select cast(LTRIM(RTRIM('45.56.78')) AS NUMBER) FROM DUAL
I don't think that you can convert '45.56.78' to a number though without removing one of the decimal points.