I have data in the following format in a sql server database table
[CPOID] [ContractPO] [ContractPOTitle]
1 10-SUP-CN-CNP-0001 Drytech
2 10-SUP-CN-CNP-0002 EC&M
I need to write a stored procedure to generate the following result
[CPOID] [ContractPO] [ContractPOTitle] [ConcatField]
1 10-SUP-CN-CNP-0001 Drytech CNP-0001-Drytech
2 10-SUP-CN-CNP-0002 EC&M CNP-0002-EC&M
where [ConcatField] generate the result using split the last two values of the [ContractPOTitle] column and combine with the [ContractPOTitle]
If the ContractPO field is always the same length, you could just do:
SELECT
CPOID,
ContractPO,
ContractPOTitle,
RIGHT(ContractPO, 8) + '-' + ContractPOTitle as [ConcatField]
FROM MyTable
Assuming that the length of the ContractPO field is not fixed AND we have to rely on stripping out the text after the next to last '-', the following SQL will work. It's a bit ugly, but these types of operations are necessary because there doesn't appear to be a LASTINDEX function available out of the box in SQL Server.
SELECT
CPOID,
ContractPO,
ContractPOTitle,
RIGHT(ContractPO, CHARINDEX('-', REVERSE(ContractPO), CHARINDEX('-', REVERSE(ContractPO)) + 1) - 1) + '-' + ContractPOTitle as [ConcatField]
FROM #myTable
Related
I uploaded some data from excel sheet to a table in sql , I would like to use part of the string that I inserted into the column PPRName and insert into another table [Verify].
The data in the column when inserted looks like this:
August 2018 [ NW: Construction MTP021 - Building and Civil Construction: Masonry NQF 3 ]
I want to insert this part of the string :
NW: Construction MTP021 - Building and Civil Construction: Masonry NQF 3
into another table [Verify] for every PPR Name in the PPRName column. The names of the PPRs vary in length but all come in same format.
I would also like to extract the August 2018 and cast it as a date and insert into my table [Verify].
I am not sure how to use Charindex and Substrings to achieve this.
i tried this but no data was returned
select SUBSTRING([PPR_Caption],charindex('[',[PPR_Caption]),charindex([PPR_Caption],']'))
FROM [dbo].[PPRS]
You incorrectly use the 2nd CHARINDEX and you incorrectly use the SUBSTRING commands.
SELECT SUBSTRING(PPR_Caption, CHARINDEX("[", PPR_Caption) + 1, CHARINDEX("]", PPR_Caption) - CHARINDEX("[", PPR_Caption) - 1)
FROM PPRS
SUBSTRING uses a start and a lenght, not the start and end point. To get the length use your end point and substract the start point (and correct the 1 position offset with -1).
In your 2nd CHARINDEX you switched the string to search in and the string to look for.
String operations like this are cumbersome in SQL Server.
Try this:
select replace(v2.str_rest, ' ]', '') as name, cast(str_start as date) as dte
from (values ('August 2018 [ NW: Construction MTP021 - Building and Civil Construction: Masonry NQF 3 ]')
) v(str) cross apply
(values (stuff(v.str, 1, charindex('[', str) + 1, ''), substring(v.str, 1, charindex('[', str) -1))
) v2(str_rest, str_start);
SQL Server is pretty good about guessing formats for converting dates, so it will actually convert the date without the day of the month.
I have the following code in a stored procedure and am trying to conditionally format a calculated number based on its length (if the number is less than 4 digits, pad with leading zeros). However, my case statement is not working. The "formattedNumber2" result is the one I'm looking for.
I'm assuming the case statement treats the variable strangely, but I also don't know of a way around this.
DECLARE #Number int = 5
SELECT
CASE
WHEN (LEN(CONVERT(VARCHAR, #Number)) > 4)
THEN #Number
ELSE RIGHT('0000' + CAST(#Number AS VARCHAR(4)), 4)
END AS formattedNumber,
LEN(CONVERT(VARCHAR, #Number)) AS numberLength,
RIGHT('0000' + CAST(#Number AS VARCHAR(4)), 4) AS formattedNumber2
I get the following results when I run the query:
formattedNumber numberLength formattedNumber2
-------------------------------------------------
5 1 0005
SQL DEMO
The problem is you are using different data type on your case , integer and string. So the CASE stay with the first type he find and convert the rest.
CASE WHEN (LEN(convert(VARCHAR, #Number)) > 4) THEN convert(VARCHAR, #Number)
This can be done a lot easier with format() since version 2012.
format(n,
'0000')
And that would also handle negative values, which your current approach apparently doesn't.
Prior 2012 it can be handled with basically replicate() and + (string concatenation).
isnull(replicate('-',
-sign(n)), '')
+
isnull(replicate('0',
4
-
len(cast(abs(n) AS varchar(10)))
),
'')
+
cast(abs(n) AS varchar(10))
(It targets integer values, choose a larger length for the varchar casts for bigint.)
db<>fiddle
I am trying to use SQL to get new policy number based on the existing one. I don't want to use update since I don't want to permanently change the records.
My policy numbers are like PFA991228-01 and I want to use SQL to modify and get PFA991228-02. So I am just updating the last 2 digits from 00 to 01 or from 05 to 06 etc. Right now I am getting error for converting varchar to int.
I am new to SQL so not sure if I can just achieve it in my first select statement instead of using sub-query
select
left(p.policynum, 9)
+ '-'
+ right('00' + convert(varchar(255), right(p.policynum, 2) + 1), 2) as newPolicy
From Company55.dbo.policy p
where p.policynum not like '%S%'
I would suggest this logic:
select (left(p.policynum, 9) + '-' +
right( '00' + try_convert(int, right(p.policynum, 2)) + 1 as varchar(255)), 2) as newPolicy
From Company55.dbo.policy P
where p.policynum not like '%S%' and
p.policynum like '%[0-9][0-9]';
Notes:
The where ensures that the output rows all end in two digits.
The try_convert() ensures that the conversion to integer succeeds -- the where is not enough.
This works for both 1- and 2- digit suffixes.
I see no reason for the subquery. right(p.policynum, 2) isn't really that much more complicated than term, for instance.
I have a database column that is a text string. Some of the values are like
"12345"
and some are as year + sequential number like:
"2016-1, 2016-2, 2016-3, 2017-1, 2017-2, 2017-3" etc.
I want to update the column values to
"2016-001, 2016-002, 2016-003, 2017-001, 2017-002, 2017-003"
for the entire table.
I'm not sure how to do this. Any help would be appreciated. I already updated my stored procedure as such to generate new numbers with zero padding like:
rptnum = cast(year(getdate()) as varchar)
+ '-' + RIGHT('000'+ISNULL(Cast((select count(*)
from dbo.tablename where rptyr = (year(getdate()))) + 1 as varchar),''),3),
Something like this should do:
select left(rptnum, charindex('-', rptnum))+right('000'+substring(rptnum, charindex('-', rptnum)+1, 10), 3)
I have a sql file which has a lot of insert statements (over 3000+).
E.g.
insert into `pubs_for_client` (`ID`, `num`, `pub_name`, `pub_address`, `publ_tele`, `publ_fax`, `pub_email`, `publ_website`, `pub_vat`, `publ_last_year`, `titles_on_backlist`, `Personnel`) values('7','5','4TH xxxx xxxx','xxxx xxxx, 16 xxxxx xxxxx, xxxxxxx, We','111111111','1111111111','support#example.net','www.example.net','15 675 4238 14',NULL,NULL,'Jane Bloggs(Sales Contact:)jane.bloggs#example.net,Joe Bloggs(Other Contact:)joe.bloggs#example.net');
I have exported this into an excel document (I did this through running the query in phpmyadmin, and exporting for an excel document). There's just one problem, as you can see in this case, there are two names & email addresses being inserted into 'Personnel'.
How easy/difficult would it be to seperate these out to display as Name, email, Name2, email2?
What about when there are three e-mails/names?
With shown data it should be easy to do
select replace(substring(substring_index(`Personnel`, ',', 1),length(substring_index(`Personnel`, ',', 1 - 1)) + 1), ',', '') personnel1,
replace(substring(substring_index(`Personnel`, ',', 2),length(substring_index(`Personnel`, ',', 2 - 1)) + 1), ',', '') personnel2,
from `pubs_for_client`
The above will split the Personnel column on delimiter ,.
You can then split these fields on delimiter ( and ) to split personnel into name, position and e-mail
The SQL will be ugly (because mysql does not have split function), but it will get the job done.
The split expression was taken from comments on mysql documentation (search for split).
You can also
CREATE FUNCTION strSplit(x varchar(255), delim varchar(12), pos int) returns varchar(255)
return replace(substring(substring_index(x, delim, pos), length(substring_index(x, delim, pos - 1)) + 1), delim, '');
After which you can user
select strSplit(`Personnel`, ',', 1), strSplit(`Personnel`, ',', 2)
from `pubs_for_client`
You could also create your own function that will extract directly names and e-mails.
As bogeymin has already said - either get the data to CSV (or convert it easily from Excel) to manipulate it. If you're on Windows, then have a look at using Notepad++ to break apart the last column.
Or... (and I'd probably do this), insert it into the database as it is (even if you insert into a dummy field, not the one you eventually want to use), then use the string manipulation functions in your varient of SQL to make either update statements, or more insert statements (whatever you need). Cerainly, MS-SQL Server can do this using things like SUBSTRING, PATINDEX etc etc...