This question already has answers here:
Why the SQL Server ignore the empty space at the end automatically?
(2 answers)
Closed 4 years ago.
I want to find out the records in which a certain column contains exactly one space and nothing else. So I wrote the first of the following queries:
select COUNT(*)
from mytable
where col = ' ' -- One space
select COUNT(*)
from mytable
where col = ' ' -- Two spaces
select COUNT(*)
from mytable
where col = ' ' -- Three spaces
However, all three queries return the exact same records. Does Microsoft SQL Server not distinguish between the amount of spaces? How can I query exactly for one, two or more spaces?
Yes, it ignores trailing spaces in comparisons.
You can try to append a delimiting character.
SELECT count(*)
FROM mytable
WHERE col + 'X' = ' X';
You can combine DATALENGTH clause with your query:
select COUNT(*)
from mytable
where col = ' '
and DATALENGTH(col) = 1
The link posted by Ivan Starostin in the comments of the OP provides a good explanation and I think it deserves a full answer instead of just a comment.
To summarize, try using LIKE instead of equality:
select COUNT(*)
from mytable
where col LIKE ' ' -- one space
And you can also use DATALENGTH to calculate how many bytes are in the field to double-check field length:
select col, DATALENGTH(col)
from mytable;
Please note that DATALENGTH will return a different value if col is a VARCHAR vs NVARCHAR. VARCHAR stores each character as 1 byte where NVARCHAR stores each character as 2 bytes since NVARCHAR is stored in Unicode.
You can replace the single space with a single character (for exampe §) and then put this character in your where condition:
declare #tmp table(col varchar(50))
insert into #tmp values
(' '),
(' '),
(' ')
select COUNT(*) as one_space_count
from #tmp
where replace(col,' ','§')='§'
select COUNT(*) as two_space_count
from #tmp
where replace(col,' ','§')='§§'
select COUNT(*) as three_space_count
from #tmp
where replace(col,' ','§')='§§§'
Results:
Related
I have a table with two columns, one is of type Varchar and the other in NVarchar.
I want to update all the rows so VarcharField = NVarcharField.
It won't let me because some of the rows contain chars that are not allowed in varchar column with the current code page.
How can I find these rows?
Is it possible to remove any char that doesn't fit the specific code page I'm using?
SQL Server 2012.
You can find the rows by attempting to convert the nvarchar() col to varchar():
select nvarcharcol
from t
where try_convert(varchar(max), nvarcharcol) is null;
Try this..
to find the rows with values that are not supported by varchar
declare #strText nvarchar(max)
set #strText = 'Keep calm and say தமிழன்டா'
select cast(#strText as varchar(max)) col1 , N'Keep calm and say தமிழன்டா' col2
Here #strText has non-english chars, When you try to cast that into varchar the non-english chars turns into ????. So the col1 and col2 are not equal.
select nvar_col
from tabl_name
where nvar_col != cast(nvar_col as varchar(max))
Is it possible to remove any char that doesn't fit the specific code page I'm using?
update tabl_name
set nvar_col = replace(cast(nvar_col as varchar(max)),'?','')
where nvar_col != cast(nvar_col as varchar(max))
Replace ? with empty string and update them.
If Gordon's approach doesn't work because you get question marks from TRY_CONVERT instead of the expected NULL, try this approach:
SELECT IsConvertible = CASE WHEN NULLIF(REPLACE(TRY_CONVERT(varchar(max), N'人物'), '?',''), '') IS NULL
THEN 'No' ELSE 'Yes' END
If you need it as filter for the rows that can't be converted:
SELECT t.*
FROM dbo.TableName t
WHERE NULLIF(REPLACE(TRY_CONVERT(varchar(max), t.NVarcharField), '?',''), '') IS NULL
In SQL Server 2014, i want to select a row which contains a word that is not present inside any of the angled brackets <>.
Sample Data:
Row 1 --> <div class="highlight"><b>Maddy</b></div>
Row 2 --> <div><b>This is highlighting an feature.</b></div>"
Here i want to filter only second row. So i used a query like
select * from table where column like '%<%>[a-zA-z0-9]*'+'highlight'+'%<%>%'"
I believe this is what you need:
LIKE 'T%[a-z]%[a-z]%'
Now would be a good time to familiarize yourself with what you can and cannot do with the LIKE operator.
Attempt:
select * from table_name where column_name like 'T[a-z]%'
select * from table_name where column_name like '[T]%'
You've nearly had the answer yourself Mathan.
The only problem that I can see with your code is that you were treating the LIKE expression as a dynamic expression.
If you are searching for a specific value in the middle of a substring then you need to wrap it in wildcards, even if you are joining search expressions together, e.g. LIKE '%highlight% + '%<%>%'
DECLARE #table table ( [column] varchar(100));
insert into #table ([column])
SELECT * FROM
(
VALUES
('<div class="highlight"><b>Maddy</b></div>'),
('<div><b>This is highlighting an feature.</b></div>')
) as [table] ([column]);
--SELECT * FROM #table;
select
[text_value] = PATINDEX('%<div>%', [column]) + LEN('<div>'),
SUBSTRING(
[column] -- what you're searching
, PATINDEX('%<div>%', [column]) + LEN('<div>') -- after the '<div>',
-- need to add the length of the 'div' as PATINDEX returns the starting location
, PATINDEX('%</div>%', [column]) - LEN('</div>') -- until the '</div>'
)
, *
from #table
where [column] like
'%<%>[a-zA-z0-9]%' -- you need to end these with the wildcard
+'%highlight%' -- or SQL-Server thinks it's the end of the sentence
+'%<%>%';
EDIT:
Adding in the PATINDEX can be used to remove the '<>' from the string. Example above removes the <div></div> but you can use that to remove any others as necessary e.g. <b></b>
I had an error in my C# code and after debugging found that
this is because on entry in a table has a trailing space.
For example 'aaa '
Now in my C# code try to set a Selected values of a combo box to this(combobox as an item with value of 'aaa' and this fails.
Clearly The solution is to fix the DB 'aaa '
Now I go to DB
and do this :
Select * from mytable
where Name='aaa'
I get Name 'aaa'
Select * from mytable
where Name='aaa '
Again I get Name 'aaa'
Select len(name) from My table
where name ='aaa'
I get 3
My question is: how by querying the table I know it has an extra space for 'aaa '?
SQL server len function excludes trailing blanks.
Consider using the DATALENGTH (Transact-SQL) function which does not trim the string.
So you can check if datalength(column) <> datalength(rtrim(column)) to find if it contains trailing spaces.
Note: if processing a unicode string, DATALENGTH will return twice the number of characters.
As Giorgi Nakeuri has explained, 'a ' and 'a' are considered equal. But you can easily find trailing spaces with LIKE:
select * from mytable where name like '% ';
And here is how to update:
update mytable set name = rtrim(name) where name like '% ';
Please help me to get value from table like below
Field A has value below
file B
13974
14098
14237
14269
....
and I need to mix values and down value in row like below
13974;14098;14237;14269;14317;14319;14392;14393;13 257;13983;13820
please help me to supports many thanks
For SQL-Server you can use,
select SUBSTRING(
(select ';' + your_column
from your_table
for xml path('')),2,10000) as csv
** 10000 is the end position of the substring. So replace this with the maximum number of characters you expect in your result.
declare #xxx nvarchar(max)
select top 10 #xxx =COALESCE(#xxx+';','')+columnName
from table
select #xxx
I have a row of strings that are in the following format:
'Order was assigned to lastname,firsname'
I need to cut this string down into just the last and first name but it is always a different name for each record.
The 'Order was assigned to' part is always the same.......
Thanks
I am using SQL Server. It is multiple records with different names in each record.
In your specific case you can use something like:
SELECT SUBSTRING(str, 23) FROM table
However, this is not very scalable, should the format of your strings ever change.
If you are using an Oracle database, you would want to use SUBSTR instead.
Edit:
For databases where the third parameter is not optional, you could use SUBSTRING(str, 23, LEN(str))
Somebody would have to test to see if this is better or worse than subtraction, as in Martin Smith's solution but gives you the same result in the end.
In addition to the SUBSTRING methods, you could also use a REPLACE function. I don't know which would have better performance over millions of rows, although I suspect that it would be the SUBSTRING - especially if you were working with CHAR instead of VARCHAR.
SELECT REPLACE(my_column, 'Order was assigned to ', '')
For SQL Server
WITH testData AS
(
SELECT 'Order was assigned to lastname,firsname' as Col1 UNION ALL
SELECT 'Order was assigned to Bloggs, Jo' as Col1
)
SELECT SUBSTRING(Col1,23,LEN(Col1)-22) AS Name
from testData
Returns
Name
---------------------------------------
lastname,firsname
Bloggs, Jo
on MS SQL Server:
declare #str varchar(100) = 'Order was assigned to lastname,firsname'
declare #strLen1 int = DATALENGTH('Order was assigned to ')
declare #strLen2 int = len(#str)
select #strlen1, #strLen2, substring(#str,#strLen1,#strLen2),
RIGHT(#str, #strlen2-#strlen1)
I would require that a colon or some other delimiter be between the message and the name.
Then you could just search for the index of that character and know that anything after it was the data you need...
Example with format changing over time:
CREATE TABLE #Temp (OrderInfo NVARCHAR(MAX))
INSERT INTO #Temp VALUES ('Order was assigned to :Smith,Mary')
INSERT INTO #Temp VALUES ('Order was assigned to :Holmes,Larry')
INSERT INTO #Temp VALUES ('New Format over time :LootAt,Me')
SELECT SUBSTRING(OrderInfo, CHARINDEX(':',OrderInfo)+1, LEN(OrderInfo))
FROM #Temp
DROP TABLE #Temp