SQL Server : add characters to a column - sql

I have problem with getting SQL code: in a column I have a value with 5 or 6 characters before that values I need put character :0 and value in column must have 7 characters.
Column
------
123456
123456
12345
12345
123456
This is my code which does not work (I am using SQL Server):
Update table
set column = CONCAT( '0', ( column ) )
where LEN( + RTRIM ( column ) ) < 7
Update table
set column = CONCAT( '0', RTRIM ( column ) )
where LEN( RTRIM( column ) ) < 7
UPDATE table
SET column = '0' + column
WHERE LEN(column) = 7
My result : after my attempt, I get 0 before values but somewhere still 0 missing.
Column
-------
0123456
0123456
012345
012345
0123456
I need :
Column
-------
0123456
0123456
0012345
0012345
0123456
Thanks for updating my code

You want to left pad the value. Here is one method:
Update table
set column = RIGHT(CONCAT( REPLICATE('0', 7), ( column ) ), 7)
where LEN( + RTRIM ( column ) ) < 7;

From your examples, I am unsure whether there are multiple values in the same field. However, assuming the value for a given row must contain a single 7 digit number with 0 padding, see the examples below. Remember that the columns that stores the padded values must be a string such as VARCHAR.
UPDATE table SET column = RIGHT('0000000' + column, 7)
This will update any value to be padded with up to 7 zeros.
If your column is currently stored as an Integer rather than a String, use the following:
UPDATE table SET TextColumn = RIGHT('0000000' + CONVERT(VARCHAR, IntColumn), 7)

Related

how to replace a value for string if letters are missing?

I ran into a problem where i have to create a 'LettersOfName' column. As name suggest I have to get letter 2,3 and 5 from ORGANISATIONNAME column and letters 2 and 3 from CLIENTLASTNAME column, then concatenate to form letters of name column. The condition is if letters of name is not equal to length 5 than replace with '22222' also if any of the letters is missing from first name and last name than replace with '22222'. I am using this query.
select
( CASE WHEN LENGTH (UPPER( SUBSTR(ORGANISATIONNAME, 2,2) || SUBSTR(ORGANISATIONNAME,5,1)) || UPPER(SUBSTR(CLIENTLASTNAME,2,2))) != '5' THEN '22222'
ELSE UPPER( SUBSTR(ORGANISATIONNAME, 2,2) || SUBSTR(ORGANISATIONNAME,5,1)) || UPPER(SUBSTR(CLIENTLASTNAME,2,2)) END)
AS LETTERSOFNAME
from client;
So, far this query runs fine, but when we have name like 'Jo Anne' or 'J Shark' it is missing letter '2' and '3' but does not replace the string with '22222'. When length is not equal to 5 it replaces with '22222'. I am using Oracle 12c.
If after the concatenations of the letters you remove all the spaces and the length of the remaining string is less than 5 then replace with '22222':
SELECT
CASE
WHEN LENGTH(REPLACE(SUBSTR(ORGANISATIONNAME, 2, 2) || SUBSTR(ORGANISATIONNAME, 5, 1) || SUBSTR(CLIENTLASTNAME, 2, 2), ' ', '')) < 5 THEN '22222'
ELSE UPPER(SUBSTR(ORGANISATIONNAME, 2, 2) || SUBSTR(ORGANISATIONNAME, 5, 1) || SUBSTR(CLIENTLASTNAME, 2, 2))
END LETTERSOFNAME
FROM client
Or with a CTE:
WITH cte AS (
SELECT
UPPER(REPLACE(
SUBSTR(ORGANISATIONNAME, 2, 2) ||
SUBSTR(ORGANISATIONNAME, 5, 1) ||
SUBSTR(CLIENTLASTNAME, 2, 2),
' ',
''
)) LETTERSOFNAME
FROM client
)
SELECT
CASE
WHEN LENGTH(LETTERSOFNAME) < 5 THEN '22222'
ELSE LETTERSOFNAME
END LETTERSOFNAME
FROM cte
See the demo.
You should first remove the white space between the string and and then apply your case statement on it
replace ('J Shark', ' ', '')
Reason is white space is being counted as a character in J Shark and that is why second and third characters are missing.
Here is an example demo.
Here is my approach:
Put both columns ORGANISATIONNAME and CLIENTLASTNAME to another table with identity column (to identify each row)
Write a function to split text by a string (in this case pass a space)
Get the identity and the splitted data to 2 tables each for column 1 and 2
Consider each table and apply your logic
Concatenate the row values separated by space, with the ID (1 record per ID)
Join the 2 tables (by IDs)
Join the 2 tables for matches in Col-Split data, and get the IDs
Now Query for the data in table in above 1

Count the number of spaces in a string

I am working on data validation and I am trying to count the number of spaces in a string. My problem is that when I count the spaces, any sting with more than one space between texts or any string with trailing space(s) are not counted
I have tried the following codes without luck. each codes gives different result but not the desired output
DECLARE #MyTbl TABLE (ID INT, Name VARCHAR(300))
INSERT INTO #MyTBL VALUES
(1, 'Alfreds Futterkiste'), -- 1 space
(2,'Mike James Ray '), -- 4 spaces 1 space between each text and 2 spaces after text
(3,'Hanari Carnes'), -- 2 spaces between text
(4,'James Michael')
-- 1
SELECT ID,
LEN(Name)-LEN(REPLACE(Name, ' ', '')) AS Count_Of_Spaces
FROM #MyTBL
-- 2
SELECT ID,
LEN(Name + ';')-LEN(REPLACE(Name,' ','')) AS Count_Of_Spaces2
FROM #MyTBL
-- 3
SELECT ID,
LEN(Name)-LEN(REPLACE(Name,' ', '')) AS Count_Of_Spaces3
FROM #MyTBL
Current output based on the first query
ID Count_Of_Spaces
1 1
2 2
3 2
4 1
Desired output
ID Count_Of_Spaces
1 1
2 4
3 2
4 1
You could use DATALENGTH:
SELECT ID,
DATALENGTH(Name)-LEN(REPLACE(Name,' ', '')) AS Count_Of_Spaces
FROM #MyTBL;
DBFiddle Demo
LEN does not count trailing spaces.
If NVARCHAR then you need to divide by 2.
DECLARE #MyTbl TABLE (ID INT, Name NVARCHAR(300))
INSERT INTO #MyTBL VALUES
(1, 'Alfreds Futterkiste'), -- 1 space
(2,'Mike James Ray '), -- 4 spaces 1 space between
-- each text and 2 spaces after text
(3,'Hanari Carnes'), -- 2 spaces between text
(4,'James Michael');
SELECT ID,
DATALENGTH(Name)/2-LEN(REPLACE(Name,' ', '')) AS Count_Of_Spaces
FROM #MyTBL;
DBFiddle Demo2
You had the answer in your attempt #2. Probably just didn't realize to do the appending in the second part(REPLACE) of your query
DECLARE #MyTbl TABLE (ID INT, Name VARCHAR(300))
INSERT INTO #MyTBL VALUES
(1, 'Alfreds Futterkiste'), -- 1 space
(2,'Mike James Ray '), -- 4 spaces 1 space between each text and 2 spaces after text
(3,'Hanari Carnes'), -- 2 spaces between text
(4,'James Michael')
-- 2
SELECT ID,
LEN(';' + Name + ';')-LEN(REPLACE(';' + Name + ';',' ','')) AS Count_Of_Spaces2
FROM #MyTBL
When I need the length of a field passed into a function or stored procedure and the field could have trailing spaces that are meant to be there, I use the following statement:-
#Len = LEN(#Parm + '.') - 1

Converts rows in columns in vertica based on key

I have table in vertica as detailed below:
key value rank
ABC 3.6138 1
ABC 1.8845 2
ABC 0.604 3
ABC -0.0351 4
ABC -0.2873 5
I want convert all the values of column- value into column separated by comma as details below:
Key value
ABC 3.6138, 1.8845, 0.604, -0.0351, -0.2873
A quick help would helpful for me a lot. Thanks in advance
Thanks.
Make use of stuff for path
SELECT key,
ConcatValue = STUFF(
(
SELECT ',' + value FROM TableName ORDER BY Rank
FOR XML PATH ('')), 1, 1, ''
)
FROM #TableName GROUP BY key

Cast string to number, interpreting null or empty string as 0

I have a Postgres table with a string column carrying numeric values. I need to convert these strings to numbers for math, but I need both NULL values as well as empty strings to be interpreted as 0.
I can convert empty strings into null values:
# select nullif('','');
nullif
--------
(1 row)
And I can convert null values into a 0:
# select coalesce(NULL,0);
coalesce
----------
0
(1 row)
And I can convert strings into numbers:
# select cast('3' as float);
float8
--------
3
(1 row)
But when I try to combine these techniques, I get errors:
# select cast( nullif( coalesce('',0), '') as float);
ERROR: invalid input syntax for integer: ""
LINE 1: select cast( nullif( coalesce('',0), '') as float);
# select coalesce(nullif('3',''),4) as hi;
ERROR: COALESCE types text and integer cannot be matched
LINE 1: select coalesce(nullif('3',''),4) as hi;
What am I doing wrong?
The types of values need to be consistent; coalescing the empty string to a 0 means that you cannot then compare it to null in the nullif. So either of these works:
# create table tests (orig varchar);
CREATE TABLE
# insert into tests (orig) values ('1'), (''), (NULL), ('0');
INSERT 0 4
# select orig, cast(coalesce(nullif(orig,''),'0') as float) as result from tests;
orig | result
------+--------
1 | 1
| 0
| 0
0 | 0
(4 rows)
# select orig, coalesce(cast(nullif(orig,'') as float),0) as result from tests;
orig | result
------+--------
1 | 1
| 0
| 0
0 | 0
(4 rows)
You could also use
cast(
case
when coalesce(orig, '') = '' then '0'
else orig
end
as float
)
You could also unwrap that a bit since you're being fairly verbose anyway:
cast(
case
when orig is null then '0'
when orig = '' then '0'
else orig
end
as float
)
or you could put the cast inside the CASE:
case
when coalesce(orig, '') = '' then 0.0
else cast(orig as float)
end
A CASE makes it a bit easier to account for any other special conditions, this also seems like a clearer expression of the logic IMO. OTOH, personal taste and all that.
Actually, you can cast NULL to int, you just can't cast an empty string to int. Assuming you want NULL in the new column if data1 contains an empty string or NULL, you can do something like this:
UPDATE table SET data2 = cast(nullif(data1, '') AS int);
or
UPDATE table SET data2 = nullif(data1, '')::int;
Reference
Check if you query parameter is empty (accepts null, empty string or value):
SELECT CAST(TO_JSON(NULLIF(:myParameter, NULL)) AS VARCHAR) IS NULL OR
CAST(TO_JSON(NULLIF(:myParameter, NULL)) AS VARCHAR) IN ('""');

How do I format numbers in a SQL table?

I need help formatting numbers in a specific way.
If a number has three decimal places or less, I would like it to remain the same.
If a number has more than three significant figures, I would like all numbers after the third significant figure to be the fractional part of the number.
123 --> Stays the same
1234 --> 123.4
How can this be done?
EDIT:
1234567 --> 123.4567
I am on SQL 2007, wishing to UPDATE the value in the table. The value is stored as a numeric.
Here is a numeric solution:
UPDATE T SET NUM = NUM/POWER(10,FLOOR(LOG10(NUM))-2)
WHERE NUM>=1000
Or the SELECT statement:
SELECT NUM, CASE WHEN NUM<1000 THEN NUM
ELSE NUM/POWER(10,FLOOR(LOG10(NUM))-2)
END AS NewNUM
FROM T
Note that the exact results can vary depending on the data type of NUM. If it is a FLOAT field, it might round the last decimal if NUM gets too large. If it is of type NUMERIC, it will add zero's to the end. If DECIMAL, you need to be careful of the precision. Note that this applies to all the update solutions already mentioned.
This could work
SELECT
CASE WHEN Num > 999 THEN Num/10
ELSE
Num
END As Num
There could be a better way, but this is what I could think of
You could do this with strings.
CREATE TABLE T
( NUM NUMERIC(38,19) );
INSERT INTO T (NUM) VALUES ( 123456789 );
INSERT INTO T (NUM) VALUES ( 12345 );
INSERT INTO T (NUM) VALUES ( 123 );
INSERT INTO T (NUM) VALUES ( 1 );
SELECT CAST(
CASE WHEN NUM < 999 THEN CAST(FLOOR(NUM) AS VARCHAR)
ELSE SUBSTRING(CAST(NUM AS VARCHAR), 1, 3) + '.'
+ SUBSTRING(CAST(FLOOR(NUM) AS VARCHAR), 4, LEN(CAST(NUM AS VARCHAR)) - 3)
END AS NUMERIC(38, 19))
FROM T
UPDATE T
SET NUM = CAST(CASE WHEN NUM < 999 THEN CAST(FLOOR(NUM) AS VARCHAR)
ELSE SUBSTRING(CAST(NUM AS VARCHAR), 1, 3) + '.'
+ SUBSTRING(CAST(FLOOR(NUM) AS VARCHAR), 4, LEN(CAST(NUM AS VARCHAR)) - 3)
END AS NUMERIC(38, 19));
I've put a working example on SQLFiddle.
Assuming strings of only integer values:
SELECT CASE WHEN LEN(Num) <= 3 THEN Num
ELSE STUFF(Num,4,0,'.')
END
FROM (VALUES('1234567'),('123'),('1234'),('12')) t(Num) --some sample values
Result:
123.4567
123
123.4
12
I answered this on a cross-post elsewhere, but for completeness:
WITH n(r) AS (
SELECT 123 UNION ALL SELECT 1234 UNION ALL SELECT 1234567
)
SELECT LEFT(r, 3) + CASE
WHEN LEN(r) > 3 THEN '.' + SUBSTRING(RTRIM(r),4,38) ELSE '' END
FROM n;