Values in Column are in format Name_city_age_ID (underscore separated).
Age was always blank. Other values may or not be blank. So values in column are like:
John_London__1223,
Mary_Paris__,
Dave____,
Smith____1012,
___2334
Now I have the age as 22 for all rows & I want to replace all values in the column, So the new columns should be:
John_London_22_1223,
Mary_Paris_22_,
Dave__22_,
Smith__22_1012,
__22_2334,
How to write the update query for this?
Using STUFF, but you should really normalize your data. This looks for the second instance of _ and adds 22.
declare #table table(col varchar(64))
insert into #table
values
('John_London__1223'),
('Mary_Paris__'),
('Dave____'),
('Smith____1012'),
('___2334')
select * from #table
--update the column
update #table
set col = stuff(col,charindex('_',col) + charindex('_',right(col,len(col) - charindex('_',col))) + 1,0,'22')
--see the results
select * from #table
Calling CHARINDEX function twice should do it. The following is the SELECT query for reviewing results, convert to UPDATE:
SELECT
str,
STUFF(str, CHARINDEX('_', str, CHARINDEX('_', str) + 1) + 1, 0, '22') AS newstr
FROM testdata
SQL Fiddle
Related
I have a conundrum....
There is a table with one NVARCHAR(50) Float column that has many rows with many numbers of various decimal lengths:
'3304.063'
'3304.0625'
'39.53'
'39.2'
I need to write a query to find only numbers with decimal places >= 4
First the query I wrote was:
SELECT
Column
FROM Tablename
WHERE Column LIKE '%.[0-9][0-9]%'
The above code finds all numbers with decimal places >= 2:
'3304.063'
'3304.0625'
'39.53'
Perfect! Now, I just need to increase the [0-9] by 2...
SELECT
Column
FROM Tablename
WHERE Column LIKE '%.[0-9][0-9][0-9][0-9]%'
this returned nothing! What?
Does anyone have an explanation as to what went wrong as well and/or a possible solution? I'm kind of stumped and my hunch is that it is some sort of 'LIKE' limitation..
Any help would be appreciated!
Thanks.
After your edit, you stated you are using FLOAT which is an approximate value stored as 4 or 8 bytes, or 7 or 15 digits of precision. The documents explicitly state that not all values in the data type range can be represented exactly. It also states you can use the STR() function when converting it which you'll need to get your formatting right. Here is how:
declare #table table (columnName float)
insert into #table
values
('3304.063'),
('3304.0625'),
('39.53'),
('39.2')
--see the conversion
select * , str(columnName,20,4)
from #table
--now use it in a where clause.
--Return all values where the last digit isn't 0 from STR() the conversion
select *
from #table
where right(str(columnName,20,4),1) != 0
OLD ANSWER
Your LIKE statement would do it, and here is another way just to show they both work.
declare #table table (columnName varchar(64))
insert into #table
values
('3304.063'),
('3304.0625'),
('39.53'),
('39.2')
select *
from #table
where len(right(columnName,len(columnName) - charindex('.',columnName))) >= 4
select *
from #table
where columnName like '%.[0-9][0-9][0-9][0-9]%'
One thing that could be causing this is a space in the number somewhere... since you said the column type was VARCHAR this is a possibility, and could be avoided by storing the value as DECIMAL
declare #table table (columnName varchar(64))
insert into #table
values
('3304.063'),
('3304. 0625'), --notice the space here
('39.53'),
('39.2')
--this would return nothing
select *
from #table
where columnName like '%.[0-9][0-9][0-9][0-9]%'
How to find out if this is the case?
select *
from #table
where columnName like '% %'
Or, anything but numbers and decimals:
select *
from #table
where columnName like '%[^.0-9]%'
The following is working fine for me:
declare #tab table (val varchar(50))
insert into #tab
select '3304.063'
union select '3304.0625'
union select '39.53'
union select '39.2'
select * from #tab
where val like '%.[0-9][0-9][0-9][0-9]%'
Assuming your table only has numerical data, you can cast them to decimal and then compare:
SELECT COLUMN
FROM tablename
WHERE CAST(COLUMN AS DECIMAL(19,4)) <> CAST(COLUMN AS DECIMAL(19,3))
You'd want to test the performance of this against using the character data type solutions that others have already suggested.
You can use REVERSE:
declare #vals table ([Val] nvarchar(50))
insert into #vals values ('3304.063'), ('3304.0625'), ('39.53'), ('39.2')
select [Val]
from #Vals
where charindex('.',reverse([Val]))>4
I have a column (XID) that contains a varchar(20) sequence in the following format: xxxzzzzzz Where X is any letter or a dash and zzzzz is a number.
I want to write a query that will strip the xxx and evaluate and return which is the highest number in the table column.
For example:
aaa1234
bac8123
g-2391
After, I would get the result of 8123
Thanks!
A bit painful in SQL Server, but possible. Here is one method that assumes that only digits appear after the first digit (which you actually specify as being the case):
select max(cast(stuff(col, 1, patindex('%[0-9]%', col) - 1, '') as float))
from t;
Note: if the last four characters are always the number you are looking for, this is probably easier to do with right():
select max(right(col, 4))
Using Numbers table
declare #string varchar(max)
set #string='abc1234'
select top 1 substring(#string,n,len(#string))
from
numbers
where n<=len(#string)
and isnumeric(substring(#string,n,1))=1
order by n
Output:1234
Using PATINDEX you can achieve it, like this -
DECLARE #test table
(
id INT,
player varchar(100)
)
INSERT #test
VALUES (1,'aaa1234'),
(2,'bac8123'),
(3,'g-2391')
SELECT
MAX(CONVERT(INT, LTRIM(SUBSTRING(player, PATINDEX('%[0-9]%', player), LEN(player)))))
FROM #test
Try:
Select MAX(RIGHT(XID,17))
from table
You can also use this method
CREATE TABLE #Tmp
(
XID VARCHAR(20)
)
INSERT INTO #Tmp(XID)
VALUES ('aaa1234'), ('bac8123'), ('g-2391')
SELECT MAX(RIGHT(XID, LEN(XID) - 3))
FROM #Tmp
I have a few million strings that relate to file paths in my database;
due to a third party program these paths have become nested like below:
C:\files\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\unique_bit_here\
I want update the entries so that thirdparty\thirdparty\etc becomes \thirdparty.
I have tried this code:
UPDATE table
SET Field = REPLACE(Field, 'tables\thirdparty\%thirdparty\%\', 'tables\thirdparty\')
WHILE EXISTS (SELECT * FROM table WHERE Field LIKE '%\thirdparty\thirdparty\%')
BEGIN
UPDATE table SET Field = REPLACE(Field, '\thirdparty\thirdparty\', '\thirdparty\')
END
So do you want something like this?
SELECT SUBSTRING('tables\thirdparty\%thirdparty\%\',0,CHARINDEX('\','tables\thirdparty\%thirdparty\%\',0)) + '\thirdparty\'
OR
UPDATE table
SET Field = REPLACE(Field, Field, (SELECT SUBSTRING(Field,0,CHARINDEX('\',Field,0)) + '\thirdparty\'))
You can avoid using a loop with the following technique:
Update TABLE
SET Field = left(Field,charindex('*',replace(Field, 'thirdparty\', '*'))-1)+'thirdparty\'+right(Field,charindex('*',reverse(replace(Field, 'thirdparty\', '*')))-1)
Its too late, but I just guess if I want replace a single word in repeating multiple time same word as he want. This will replace all with append a single time '\thirdparty'...
Check this.
Declare #table table(Field varchar(max))
insert into #table values('C:\files\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\unique_bit_here\')
,('C:\files\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\unique_bit_here\1')
,('C:\files\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\unique_bit_here\2')
,('C:\files\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\unique_bit_here\3')
,('C:\files\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\thirdparty\unique_bit_here\4')
UPDATE #table
SET Field = SUBSTRING (Field, 1, CHARINDEX('\thirdparty', Field ) ) + 'thirdparty\'
--replace (Field , 'thirdparty\' ,'')
+ reverse( SUBSTRING ( REVERSE(Field), 1, CHARINDEX(reverse('\thirdparty'), REVERSE(Field) )-2 ) )
--REPLACE(Field, 'tables\thirdparty\%thirdparty\%\', 'tables\thirdparty\')
select * from #table
I have a column called original_filename which contains text. within the text there is a file ID which I want to extract. The description starts with "error_rows_" as shown below. However the file ID's vary in length i.e 999 to 999999 followed by additional text.
error_rows_90349_2014-04-10_00-00-00_Transaction-Login_TheHut.gpg
error_rows_904003_2014-04-10_12-00-00_Transaction-Login_TheHut.gpg
error_rows_90403_2014-04-10_12-00-00_Transaction-Registration_TheHut.gpg
error_rows_9060_2014-04-11_00-00-00_Transaction-Login_TheHut.gpg
Can someone help me with the sql to extract this. the end result should be:
90349
904003
90403
9060
I have been trying to use charindex withou success
Try this:
DECLARE #Test TABLE (TestData VARCHAR(500));
INSERT INTO #Test SELECT 'error_rows_90349_2014-04-10_00-00-00_Transaction-Login_TheHut.gpg';
INSERT INTO #Test SELECT 'error_rows_904003_2014-04-10_12-00-00_Transaction-Login_TheHut.gpg';
INSERT INTO #Test SELECT 'error_rows_90403_2014-04-10_12-00-00_Transaction-Registration_TheHut.gpg';
INSERT INTO #Test SELECT 'error_rows_9060_2014-04-11_00-00-00_Transaction-Login_TheHut.gpg';
SELECT
*,
CONVERT(INT, SUBSTRING(TestData, 12, CHARINDEX('_', TestData, 12) - 12))
FROM
#Test;
Results:
90349
904003
90403
9060
Hello I have a column in sql and I need to insert a "." before the last two characters. The column is not fixed length. Can someone help me go about this?
You can do it with an UPDATE and SUBSTRING.
UPDATE table
SET column = (SELECT SUBSTRING(column, 1, LEN(column)-2)
+ '.'
+ SUBSTRING(column, LEN(column)-1, LEN(column))
If you would like to check what the query will do to your column, just use:
SELECT
SUBSTRING(column, 1, LEN(column)-2)
+ '.'
+ SUBSTRING(column, LEN(column)-1, LEN(column))
FROM table
It looks messy but this should do it:
SELECT LEFT(COL_NAME, LEN(COL_NAME)-1)+'.'+RIGHT(COL_NAME,1)
FROM Table
Or if you want to update the value in the database rather than just the output
Update Table
SET COL_NAME = LEFT(COL_NAME, LEN(COL_NAME)-1)+'.'+RIGHT(COL_NAME,1)
You can use sp_rename like this:
EXEC sp_rename 'dbo.DatabaseName.ColumnName', 'ColumnNa.me', 'COLUMN';
If you need to apply this to multiple columns, then I would suggest using the substring method. No real use to do it for just one UPDATE on a column.
Question is not very clear. If you are trying to insert . before last 2 characters into the column data, you could use STUFF() function.
For ex:
Declare #s varchar(50) = '12345678'
Select Stuff(#s, Len(#s)-1, 0, '.')
--> 123456.78
Applying to your table query:
Select Stuff(yourCol, Len(yourCol)-1, 0, '.')
From yourTable
Please note that If Len(yourCol) is less than 2, a null string will be returned.