How to combine SQL queries for same column? - sql

I have searched but not found any examples for my particular problem.
I am trying to strip some unwanted text from a column containing department names. I am trying to combine 2 queries to do this.
This first query strips all characters after the colon in the name:
SELECT
CASE WHEN CHARINDEX(':', DB.Table.DEPT)>0
THEN
LEFT(DB.Table.DEPT, CHARINDEX(':', DB.Table.DEPT)-1)
ELSE
DB.Table.DEPT
END
FROM
DB.Table
The second query strips the prefix from the name:
SELECT
REPLACE(
REPLACE(
REPLACE (DB.Table.DEPT,'[NA1] ','')
,'[NA2] ', '')
,'[NA3] ', '')
FROM
DB.Table
Both of these work great independent of each other, but when I try to combine them it fails.
SELECT
CASE WHEN CHARINDEX(':', DB.Table.DEPT)>0
THEN
LEFT(DB.Table.DEPT, CHARINDEX(':', DB.Table.DEPT)-1)
ELSE
DB.Table.DEPT
END
FROM
(SELECT
REPLACE(
REPLACE(
REPLACE (DB.Table.DEPT,'[NA1] ','')
,'[NA2] ', '')
,'[NA3] ', '')
FROM
DB.Table)
I could really use some guidance with this.
Thanks in advance.

Your query is syntactically incorrect, because you need an alias for the subquery and for the expression result:
SELECT (CASE WHEN CHARINDEX(':', DEPT)>0
THEN LEFT(DEPT, CHARINDEX(':', DEPT)-1)
ELSE DEPT
END)
FROM (SELECT REPLACE(REPLACE(REPLACE(t.DEPT,'[NA1] ',''
), '[NA2] ', ''
), '[NA3] ', ''
) as DEPT
FROM DB.Table t
) t;
EDIT:
To see both the original and new department:
SELECT (CASE WHEN CHARINDEX(':', new_DEPT) > 0
THEN LEFT(new_DEPT, CHARINDEX(':', newj_DEPT)-1)
ELSE new_DEPT
END),
Orig_DEPT
FROM (SELECT REPLACE(REPLACE(REPLACE(t.DEPT,'[NA1] ',''
), '[NA2] ', ''
), '[NA3] ', ''
) as new_DEPT,
t.DEPT as orig_DEPT
FROM DB.Table t
) t

You should always name your subquerys.
Try this:
SELECT
CASE WHEN CHARINDEX(':', x.DEPT)>0
THEN
LEFT(x.DEPT, CHARINDEX(':', x.DEPT)-1)
ELSE
x.DEPT
END AS DEPT
FROM
(
SELECT
REPLACE(REPLACE(REPLACE (DEPT,'[NA1] ','') ,'[NA2] ', ''),'[NA3] ', '') AS DEPT
FROM
DB.Table
) x

Related

SQL Server : to get last 4 character in first column and get the first letter of the words in 2nd column but ignore non alphabets

Can I check will it be possible to run SQL with this requirement? I trying to get a new value for new column from these 2 existing columns ID and Description.
For ID, simply retrieve last 4 characters
For Description, would like to get the first alphabets for each word but ignore the numbers & symbols.
SQL Server has lousy string processing capabilities. Even split_string() doesn't preserve the order of the words that it finds.
One approach to this uses a recursive CTE to split the strings and accumulate the initials:
with t as (
select v.*
from (values (2004120, 'soccer field 2010'), (2004121, 'ruby field')) v(id, description)
),
cte as (
select id, description, convert(varchar(max), left(description, charindex(' ', description + ' '))) as word,
convert(varchar(max), stuff(description, 1, charindex(' ', description + ' ') , '')) as rest,
1 as lev,
(case when description like '[a-zA-Z]%' then convert(varchar(max), left(description, 1)) else '' end) as inits
from t
union all
select id, description, convert(varchar(max), left(rest, charindex(' ', rest + ' '))) as word,
convert(varchar(max), stuff(rest, 1, charindex(' ', rest + ' ') , '')) as rest,
lev + 1,
(case when rest like '[a-zA-Z]%' then convert(varchar(max), inits + left(rest, 1)) else inits end) as inits
from cte
where rest > ''
)
select id, description, inits + right(id, 4)
from (select cte.*, max(lev) over (partition by id) as max_lev
from cte
) cte
where lev = max_lev;
Here is a db<>fiddle.
To get the last 4 numbers of the ID you could use:
SELECT Id%10000 as New_Id from Tablename;
To get the starting of each Word you could use(letting the answer be String2):
LEFT(Description,1)
This is equivalent to using SUBSTRING(Description,1,1)
This helps you get the first letter of each word.
To concatenate both of them you could use the CONCAT function:
SELECT CONCAT(String2,New_Id)
See more on the CONCAT function here

How can I CONCAT portions of three columns to one new column

I am trying to create a new column in my results that is made up on the first 3 characters of "PrimaryName", all of "VendorCity", and the first 5 characters of "VendorZip"
SELECT,VendorName
,replace(PrimaryVendorLocationName,' ','') as PrimaryName
,replace(PrimaryVendorLocationCity,' ','') as VendorCity
,replace(PrimaryVendorLocationZipCode,' ','') as VendorZip
FROM [table]
As you can see I also need to remove spaces to ensure a cleaner return. I would like to call the new column "NewVendorCode". So a record that originates like this:
R A Slack
Chicago Heights
60654-1234
Will return this:
RASChicagoHeights60654
You can use the following, using LEFT (MySQL / TSQL):
SELECT CONCAT(
LEFT(REPLACE(PrimaryVendorLocationName, ' ', ''), 3),
REPLACE(PrimaryVendorLocationCity, ' ', ''),
LEFT(REPLACE(PrimaryVendorLocationZipCode, ' ', ''), 5)
) FROM table_name
... or you can use SUBSTRING (MySQL / TSQL) (instead of LEFT):
SELECT CONCAT(
SUBSTRING(REPLACE(PrimaryVendorLocationName, ' ', ''), 1, 3),
REPLACE(PrimaryVendorLocationCity, ' ', ''),
SUBSTRING(REPLACE(PrimaryVendorLocationZipCode, ' ', ''), 1, 5)
) FROM table_name
Note: As you can see the SELECT querys work on MySQL and TSQL without change.
demo (MySQL): https://www.db-fiddle.com/f/wTuKzosFgkEuKXtruCTCxg/0
demo (TSQL): http://sqlfiddle.com/#!18/dbc98/1/1
You can use the following code:
SELECT VendorName+
replace(PrimaryVendorLocationName,' ','') +
replace(PrimaryVendorLocationCity,' ','') +
replace(PrimaryVendorLocationZipCode,' ','') as NewVendorCode
SELECT VendorName
,PrimaryName
,VendorCity
,VendorZip
,CONCAT(LEFT(PrimaryName,3),VendorCity,LEFT(VendorZip,5)) As NewVendorCode
FROM (
SELECT VendorName
,replace(PrimaryVendorLocationName,' ','') as PrimaryName
,replace(PrimaryVendorLocationCity,' ','') as VendorCity
,replace(PrimaryVendorLocationZipCode,' ','') as VendorZip
FROM [table]
)

SQL - re.split: BY comma THEN space

I want to split the following string into City, Province, Postal Code.
Thank you so much for the help!!!!
Description: Split by comma, then split by space only once.
A = 'Vaughan, ON L6D 9X0'
Result:
(Vaughan, ON, L6D9X0)
Attempt:
re.split(',|/s[1]', A)
Try This,
This selected the values into rows, maybe you can pivot the cte C2 same in order to get it as columns
WITH CTE
AS
(
SELECT
1 Seq,
'Vaughan, ON L6D 9X0' "Txt"
UNION ALL
SELECT
Seq+1 "Seq",
Txt = CASE WHEN Txt LIKE '% %'
THEN LTRIM(RTRIM(SUBSTRING(Txt,CHARINDEX(' ',Txt),LEN(Txt))))
ELSE NULL END
FROM CTE
WHERE ISNULL(txt,'')<>''
),C2
AS
(
SELECT
CASE Seq
WHEN 1 THEN 'City'
WHEN 2 THEN 'Province'
ELSE 'PostalCode' END "Head",
CASE Seq
WHEN 1
THEN SUBSTRING(Txt,1,CHARINDEX(',',Txt)-1)
WHEN 2
THEN SUBSTRING(Txt,1,CHARINDEX(' ',Txt)-1)
ELSE Txt END "Txt"
FROM CTE
WHERE Seq<4
)
SELECT
*
FROM C2;
If you have multiple rows that need to be parsed in the same way then, you can give the same in the select statement of 1st CTE and in that case, the logic for Seq on the first select might need to be changed. As per the above, the output will be as follows
With Postgres you can do that using:
select split_part(a, ',', 1) as city,
left(trim(split_part(a,',',2)), strpos(trim(split_part(a,',',2)), ' ')),
substr(trim(split_part(a,',',2)) as province, strpos(trim(split_part(a,',',2)), ' ') + 1) as postal_code
from the_table;
This can be made a bit more readable by using a derived table:
select city,
left(second_part, strpos(second_part, ' ')) as province,
substr(second_part, strpos(second_part, ' ') + 1) as postal_code
from (
select split_part(a, ',', 1) as city,
trim(split_part(a, ',', 2)) as second_part
from the_table
) t
IF, You are working with Microsoft SQL Server, then you could use SUBSTRING() &CHARINDEX() function to find specific Char index to split the string values.
SELECT SUBSTRING(<column>, 1, CHARINDEX(',', <column>)-1) City,
SUBSTRING(SUBSTRING(<column>, CHARINDEX(' ', <column>)+1, LEN(<column>)), 1, CHARINDEX(' ', SUBSTRING(<column>, CHARINDEX(' ', <column>)+1, LEN(<column>)))) Province,
SUBSTRING(SUBSTRING(<column>, CHARINDEX(' ', <column>)+1, LEN(<column>)), CHARINDEX(' ', SUBSTRING(<column>, CHARINDEX(' ', <column>)+1, LEN(<column>)))+1, LEN(<column>)) [Postal Code];
Desired Output :
City Province Postal Code
Vaughan ON L6D 9X0

SQL count string matches

Please take a look at this simple SQL server database :
I want the result to have 3 column, and the column "CountString" is the total number of string that matches ('this','is', 'count', 'example').
I have managed to detect those words using this query, but it can`t detect multiple words :
SELECT
productid,
NAME,
((CASE
WHEN Concat(' ', NAME, ' ') LIKE '% this %' THEN 1
ELSE 0
END) + (CASE
WHEN Concat(' ', NAME, ' ') LIKE '% is %' THEN 1
ELSE 0
END) + (CASE
WHEN Concat(' ', NAME, ' ') LIKE '% count %' THEN 1
ELSE 0
END) + (CASE
WHEN
Concat(' ', NAME, ' ') LIKE '% example %' THEN 1
ELSE 0
END)) AS CountString
FROM product;
However, if the name for productID 1 is "this is count this example". I want it to be counted as 5. Could you solve this ?
Create Table product(productid int, NAME varchar(100))
Insert Into product Values(1,'this is this example')
Insert Into product Values(2,'this is this this count this example')
SELECT productid,count(*) as CountString
FROM
(
SELECT A.[productid],
Split.a.value('.', 'VARCHAR(100)') AS String
FROM (SELECT [productid],
CAST ('<M>' + REPLACE([NAME], ' ', '</M><M>') + '</M>' AS XML) AS String
FROM product) AS A
CROSS APPLY String.nodes ('/M') AS Split(a)
) As Word
WHERE String in ('this','is','count','example')
Group by productid
Try this
DECLARE #TableString TABLE(ID INT IDENTITY,String nvarchar(max))
INSERT INTO #TableString(String)
SELECT 'this is count this example' UNION ALL
SELECT 'Bearing Ball' UNION ALL
SELECT 'BB Ball Bearing ' UNION ALL
SELECT 'this is example'
-- Here the delimeter is space
SELECT id AS productid, COUNT(stringValue) AS StringValueCount FROM
(
SELECT id ,
Split.a.value('.', 'VARCHAR(1000)') AS stringValue
FROM (
SELECT id,CAST('<S>' + REPLACE(String, ' ', '</S><S>') + '</S>' AS XML) AS String
FROM #TableString
) AS A
CROSS APPLY String.nodes('/S') AS Split(a)
)Dt
WHERE dt.stringValue in ('this','is','count','example')
GROUP BY id
Result
productid StringValueCount
-----------------------------
1 5
4 3

SQL to find string in select

I have a select statement like this:
SELECT ColumnA,
CASE ColumnB = 'England' THEN ...
In the part after the THEN statement, i want to take the numbers from ColumnC,
e.g. ColumnC value = ABC 123 DEF, and i need the '123' part.
Does anyone know the sql code i can use to do this within the select when the '123' will always be in between the only 2 spaces in the string? (MS SQL)
The main key is that you need to use ColumnC LIKE '% % %' so that it does not fail when the data does not contain two spaces.
If your numbers are going to be less than 20-char long, you can use this
SELECT ColumnA,
CASE WHEN ColumnB = 'England' AND ColumnC LIKE '% % %' THEN
RTRIM(LEFT(REPLACE(STUFF(columnc, 1, PatIndex('% %', columnc), ''), ' ', REPLICATE(' ', 20)),20))
ELSE ....
Or you can use this
SELECT ColumnA,
CASE WHEN ColumnB = 'England' AND ColumnC LIKE '% % %' THEN
SUBSTRING(
SUBSTRING(
ColumnC,
1,
CHARINDEX(' ',ColumnC,CHARINDEX(' ', ColumnC)+1)-1),
1+CHARINDEX(' ', ColumnC),
LEN(ColumnC))
ELSE ....
You can use a combination of CHARINDEX and SUBSTRING:
DECLARE #Test TABLE(ColumnC varchar(100))
INSERT #Test
VALUES ('ABC 123 DEF')
SELECT SUBSTRING(ColumnC,
CHARINDEX(' ', ColumnC) + 1, -- first space
CHARINDEX(' ', ColumnC, CHARINDEX(' ', ColumnC) + 1)
- CHARINDEX(' ', ColumnC)) -- length from first to second space
FROM #Test
This works as expected for the sample string provided.
SUBSTRING_INDEX(SUBSTRING_INDEX( ColumnC , ' ', 2 ),' ',-1)