Snowflake convert string into output - snowflake-cloud-data-platform

select ' \''||
CAST(NVL(X.TYPE,'') AS VARCHAR(50))||'\
\''||CAST(NVL(X.ID_1,'') AS VARCHAR(50))||'\
- \''||
---CAST(NVL(X.ID_2,'') AS VARCHAR(50))
CASE WHEN X.ID_2 IS NOT NULL
THEN X.ID_2
WHEN X.ID_2 IS NULL
THEN 'NULL' END
||'\ '
from
( select ....)
select query returns value for three columns.
Above code gives o/p as 'R'32 - 'NULL
Expected is 'R 32 - NULL'
Can someone help

Using CONCAT and COALESCE:
SELECT *,
CONCAT('\'',COALESCE(X.TYPE,''), ' ' ,
COALESCE(X.ID_1::TEXT, ''), ' - ' ,
COALESCE(X.ID_2::TEXT, 'NULL'), '\'') AS res
FROM (SELECT 'R' AS TYPE, 32::INT AS ID_1, NULL AS ID_2) AS X;
Output:

#Rahul, I believe you are looking for something like this? The escaped apostrophes were the culprit from Lukasz's answer.
SELECT
CONCAT(
COALESCE(X.TYPE,'')
, CHAR(32) /* <-- ADDS A SPACE */
, COALESCE(X.ID_1::TEXT, '')
, CHAR(32), CHAR(45), CHAR(32) /* <-- ADDS A SPACE DASH SPACE */
, COALESCE(X.ID_2::TEXT, 'NULL')
) AS res
FROM (SELECT 'R' AS TYPE, 32::INT AS ID_1, NULL AS ID_2) AS X
;
Returns:
R 32 - NULL

Related

TSQL - Move any text after CR/LF to a new column

We have an address field in our database that I need to split up into two columns (Address1 and Address2). I'm looking for a way to split up this string after the CR/LF section.
How can I do this? I'm using SSMS 2016
Something like this could be used -
Carriage return is char(13)
DECLARE #Str table (str VARCHAR(100))
insert into #Str values
('Test
Word'),
('NoCRLF')
SELECT CASE WHEN CHARINDEX(CHAR(13), Str ) > 0 THEN SUBSTRING(Str , 1, CHARINDEX(CHAR(13), Str ) - 1) ELSE Str END AS [First],
CASE WHEN CHARINDEX(CHAR(13), Str ) > 0 THEN SUBSTRING(Str , CHARINDEX(CHAR(13), Str ) + 1, LEN(Str )) ELSE NULL END AS [Last]
FROM #Str
You can use CHARINDEX to find if your address has new line character or not. and based on that you can split up you address using SUBSTRING.
For address1, you should start from position 1 and end at position 1 less than index of new line character.
Similarly for address2, you should start from position 1 more than index of new line character and end the end of the string.
Code below handles cases like when there is no CHAR(13) you will get Address1 only and Address2 will be NULL. Same way if Address is NULL or Blank space it will handle it.
Below is the sample code:
DECLARE #AddressTable AS TABLE
(
Address nvarchar(MAX) NULL,
Address1 nvarchar(MAX) NULL,
Address2 nvarchar(MAX) NULL
)
INSERT #AddressTable (Address)
SELECT '1600 Pennsylvania Avenue' + CHAR(13) + 'Washington DC ' Address UNION ALL
SELECT '221 B Baker St, London, England' Address UNION ALL
SELECT NULL Address UNION ALL
SELECT '' Address UNION ALL
SELECT '11 Wall Street' + CHAR(13) + 'New York, NY' Address
SELECT
CASE
WHEN CHARINDEX(CHAR(13), Address) > 0 THEN SUBSTRING(Address, 1, CHARINDEX(CHAR(13), Address) - 1) + '|'
ELSE Address END
Address1,
CASE
WHEN CHARINDEX(CHAR(13), Address) > 0 THEN SUBSTRING(Address, CHARINDEX(CHAR(13), Address) + 1, LEN(Address)) + '|'
ELSE NULL END
Address2
FROM #AddressTable
From SQL Server 2016 there is a string_split function:
https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql

Remove last character from string column in SQL

I have these special characters " ||~|| " at the end of each value in column X. I need to remove these special characters.
Right now I am using this syntax, but it doesn't seem to accomplish the task for all rows.
set [Customer Num] = substring(ltrim(rtrim([Customer Num])),3,len([Customer Num]))
Try this options,
Declare #myStr varchar(50) = 'amol~'
--If want to remove char ~ of any position
Select REPLACE(#myStr,'~','')
Set #myStr = '~amol~'
Select REPLACE(#myStr,'~','')
Set #myStr = '~am~ol~'
Select REPLACE(#myStr,'~','')
--If want to remove character ~ at Last position & existance of char ~ is inconsistent
Set #myStr ='amol~'
Select Case When RIGHT(#myStr,1) = '~'
Then LEFT(#myStr,len(#myStr) - 1)
Else #myStr
End
If you are looking to replace ||~|| Then try this,
Declare #myStr varchar(50) = 'amol ||~|| '
--If want to remove string ||~| of any position
Select REPLACE(#myStr,'||~||','')
Set #myStr = '||~||amol||~||'
Select REPLACE(#myStr,'||~||','')
Set #myStr = '||~||am||~||ol||~||'
Select REPLACE(#myStr,'||~||','')
--If want to remove string ||~| at Last position & existance of char ||~| is inconsistent
Set #myStr ='amol||~||'
Select Case When RIGHT(#myStr,5) = '||~||'
Then LEFT(#myStr,len(#myStr) - 5)
Else #myStr
End
If you know for sure that your values end with the Special String, try
substring ( [Customer Num], 1, length([Customer Num]) - length(' ||~|| ') )
It's better, however, to safeguard against accidental Deletions:
substring (
[Customer Num]
, 1
, Case coalesce(substr( [Customer Num], length([Customer Num]) - length(' ||~|| '), '_' )
When ' ||~|| ' then length([Customer Num]) - length(' ||~|| ')
Else length([Customer Num])
End
)
If your rdbms Supports regular expressions, this simplifies to (using Oracle Syntax)
Regexp_replace ( [Customer Num], ' \|\|~\|\| $', '')
Assuming you have to remove last 3 characters of ColumnX
set [ColumnX] = substring(ltrim(rtrim([ColumnX])),0,len([ColumnX]) - 3)
This works
update [Table] set [Customer Num] = (substring(ltrim(rtrim([Customer Num])),0,len([Customer Num]) - 3))
where [Customer Num] like '%only text containing this string%'

Get null if non numeric or the actual numeric value in TSQL

I'm trying to get the numeric value of a string if isnumeric() function returns 1 or NULL if it returns 0. But I only get if it's numeric I get 1 or null if non numeric.
Is it possible to return the numeric value (instead of 1) using something like the code below?
select '14-154877-0' as actual_string, replace('14-154877-0', '-', '') as numeric_value, nullif(isnumeric(replace('14-154877-0', '-', '')), 0) as numeric_value_or_null /* Here I wold like to return the numeric value instead of 1 */
select 'some text' as actual_string, replace('some text', '-', '') as numeric_value, nullif(isnumeric(replace('some text', '-', '')), 0) as numeric_value_or_null /* OK */
Sample data
The insert statements are a result of the excel concatenation function.
As sugested, I used the case expression and the try_convert() (for MSSQL 2012) function and they work fine. Is there a better way of doing this kind of insert?
if object_id('tempdb..#temp_table') is not null
begin
drop table #temp_table;
end;
create table #temp_table (
int_column int,
varchar_column varchar(50)
);
insert into #temp_table (int_column, varchar_column) values (case when isnumeric(replace('111----111', '-', '')) = 1 then replace('111----111', '-', '') end, 'string data 1');
insert into #temp_table (int_column, varchar_column) values (case when isnumeric(replace('text', '-', '')) = 1 then replace('text', '-', '') end, 'string data 2');
insert into #temp_table (int_column, varchar_column) values (try_convert(int, replace('258--', '-', '')), 'string data 3');
insert into #temp_table (int_column, varchar_column) values (try_convert(int, replace('123', '-', '')), 'string data 4');
select * from #temp_table;
/*
| int_column | varchar_column |
| 111111 | string data 1 |
| NULL | string data 2 |
| 258 | string data 3 |
| 123 | string data 4 |
*/
Perhaps:
SELECT value as actual_string
, replace(value, '-', '') as numeric_value
, CASE ISNUMERIC(replace(value, '-', ''))
WHEN 1 THEN CAST(replace(value, '-', '') AS FLOAT)
ELSE NULL END AS numeric_value_or_null
FROM TableName
Fiddle inside
If you are on 2012 (select appropriate datatype for your data, I've assumed INT)
SELECT TRY_CONVERT(INT, replace(value, '-', ''))
What's wrong with using a case statement? e.g.
declare #text varchar(50)
set #text = '747467'
select
case
when isnumeric(#text) <> 1 then null
else cast(#text as decimal)
end as numeric_or_null
select '14-154877-0' as actual_string, replace('14-154877-0', '-', '') as numeric_value, case when isnumeric(replace('14-154877-0', '-', ''))=1 then Cast(replace('14-154877-0', '-', '') as Numeric) else null end as numeric_value_or_null /* Here I wold like to return the numeric value instead of 1 */

SQL: Concatenate column values in a single row into a string separated by comma

Let's say I have a table like this in SQL Server:
Id City Province Country
1 Vancouver British Columbia Canada
2 New York null null
3 null Adama null
4 null null France
5 Winnepeg Manitoba null
6 null Quebec Canada
7 Seattle null USA
How can I get a query result so that the location is a concatenation of the City, Province, and Country separated by ", ", with nulls omitted. I'd like to ensure that there aren't any trailing comma, preceding commas, or empty strings. For example:
Id Location
1 Vancouver, British Columbia, Canada
2 New York
3 Adama
4 France
5 Winnepeg, Manitoba
6 Quebec, Canada
7 Seattle, USA
I think this takes care of all of the issues I spotted in other answers. No need to test the length of the output or check if the leading character is a comma, no worry about concatenating non-string types, no significant increase in complexity when other columns (e.g. Postal Code) are inevitably added...
DECLARE #x TABLE(Id INT, City VARCHAR(32), Province VARCHAR(32), Country VARCHAR(32));
INSERT #x(Id, City, Province, Country) VALUES
(1,'Vancouver','British Columbia','Canada'),
(2,'New York' , null , null ),
(3, null ,'Adama' , null ),
(4, null , null ,'France'),
(5,'Winnepeg' ,'Manitoba' , null ),
(6, null ,'Quebec' ,'Canada'),
(7,'Seattle' , null ,'USA' );
SELECT Id, Location = STUFF(
COALESCE(', ' + RTRIM(City), '')
+ COALESCE(', ' + RTRIM(Province), '')
+ COALESCE(', ' + RTRIM(Country), '')
, 1, 2, '')
FROM #x;
SQL Server 2012 added a new T-SQL function called CONCAT, but it is not useful here, since you still have to optionally include commas between discovered values, and there is no facility to do that - it just munges values together with no option for a separator. This avoids having to worry about non-string types, but doesn't allow you to handle nulls vs. non-nulls very elegantly.
select Id ,
Coalesce( City + ',' +Province + ',' + Country,
City+ ',' + Province,
Province + ',' + Country,
City+ ',' + Country,
City,
Province,
Country
) as location
from table
This is a hard problem, because the commas have to go in-between:
select id, coalesce(city+', ', '')+coalesce(province+', ', '')+coalesce(country, '')
from t
seems like it should work, but we can get an extraneous comma at the end, such as when country is NULL. So, it needs to be a bit more complicated:
select id,
(case when right(val, 2) = ', ' then left(val, len(val) - 1)
else val
end) as val
from (select id, coalesce(city+', ', '')+coalesce(province+', ', '')+coalesce(country, '') as val
from t
) t
Without a lot of intermediate logic, I think the simplest way is to add a comma to each element, and then remove any extraneous comma at the end.
Use the '+' operator.
Understand that null values don't work with the '+' operator (so for example: 'Winnepeg' + null = null), so be sure to use the ISNULL() or COALESCE() functions to replace nulls with an empty string, e.g.: ISNULL('Winnepeg','') + ISNULL(null,'').
Also, if it is even remotely possible that one of your collumns could be interpreted as a number, then be sure to use the CAST() function as well, in order to avoid error returns, e.g.: CAST('Winnepeg' as varchar(100)).
Most of the examples so far neglect one or more pieces of this. Also -- some of the examples use subqueries or do a length check, which you really ought not to do -- just not necessary -- though your optimizer might save you anyway if you do.
Good Luck
ugly but it will work for MS SQL:
select
id,
case
when right(rtrim(coalesce(city + ', ','') + coalesce(province + ', ','') + coalesce(country,'')),1)=',' then left(rtrim(coalesce(city + ', ','') + coalesce(province + ', ','') + coalesce(country,'')),LEN(rtrim(coalesce(city + ', ','') + coalesce(province + ', ','') + coalesce(country,'')))-1)
else rtrim(coalesce(city + ', ','') + coalesce(province + ', ','') + coalesce(country,''))
end
from
table
I know it's an old question, but should someone should stumble upon this today, SQL Server 2017 and later has the STRING_AGG function, with the WITHIN GROUP option :
with level1 as
(select id,city as varcharColumn,1 as columnRanking from mytable
union
select id,province,2 from mytable
union
select id,country,3 from mytable)
select STRING_AGG(varcharColumn,', ')
within group(order by columnRanking)
from level1
group by id
Should empty strings exist aside of nulls, they should be excluded with some WHERE clause in level1.
Here is an option:
SELECT (CASE WHEN City IS NULL THEN '' ELSE City + ', ' END) +
(CASE WHEN Province IS NULL THEN '' ELSE Province + ', ' END) +
(CASE WHEN Country IS NULL THEN '' ELSE Country END) AS LOCATION
FROM MYTABLE

in SQL SELECT statement :conditionally removing comma operator from field

I have a select statement like
SELECT 'Name' = customer_fname+ ', ' + customer_lname
FROM customers
Its output is like:
peter, willson
jenny, Mark
Now, if customer_fname is null, then output will be:
, willson
, Mark
If customer_lname is null then:
peter,
jenny,
And if both customer_fname and customer_lname are null then only the comma will be displayed.
I want to remove the comma. How do I do this?
Ordinarily I would suggest using the ISNULL operator. However, as you need to check on both fields, the logic becomes a bit nasty. Therefore, I would suggest using a CASE statement.
SELECT CASE
WHEN first_name IS NULL AND last_name IS NULL THEN ''
WHEN first_name IS NULL AND last_name IS NOT NULL THEN last_name
WHEN first_name IS NOT NULL AND last_name IS NULL THEN first_name
ELSE last_name + ', ' + first_name
END
FROM customers
EDIT For dknaack - an ISNULL solution :)
SELECT ISNULL(last_name + ', ' + first_name,
ISNULL(last_name,
ISNULL(first_name, '')))
FROM Customers
You should use operator CASE and function ISNULL.
Please use below query: thanks
SELECT 'Name' =
(CASE WHEN customer_fname IS NULL OR customer_lname IS NULL THEN (customer_fname + ' ' + customer_lname )
ELSE customer_fname+ ', ' + customer_lname END)
FROM customers
You can use case function in SQL Server:
SELECT 'Name' = customer_fname+ case when customer_fname is not null then ',' + customer_lname FROM customers
careful with NULL values with [+] operator :
unless you set the database parameter CONCAT_NULL_YIELDS_NULL to OFF,
NULL+'any non null string' returns NULL, not empty string
SELECT ISNULL(customer_fname,'')+ ISNULL(', '+ customer_lname,'') [Name]
FROM customers

Resources