Extracting month using substring in sql server - sql-server

I have the following code
#FiscalMonth As varchar(MAX) ='[Dim Date].[Fiscal].[Fiscal Month Number].&[10]&[2014]&[4]&[1]'
In my case the month will be 10 . I have tried the following code
SET #FiscalMonthNumber = cast(substring(right(#FiscalMonth,18),1,2) as nvarchar(max))
The code above works fine but when I have
#FiscalMonth As varchar(MAX) ='[Dim Date].[Fiscal].[Fiscal Month Number].&[10]&[2014]&[11]&[1]'
I have as result 0] which is incorrect .

Ugh. This assumes that the first time you encounter a pattern like '[n' (where n is any number, and it will occur within the first 8000 characters of the string), that is the month:
DECLARE #fm VARCHAR(MAX);
SET #fm = '[Dim Date].[Fiscal].[Fiscal Month Number].&[10]&[2014]&[4]&[1]';
SELECT SUBSTRING(#fm, PATINDEX('%[[][0-9]%', #fm) + 1,
CHARINDEX(']', SUBSTRING(#fm, PATINDEX('%[[][0-9]%', #fm) + 1, 8000)) - 1);
Result:
----------
10
If there are other possible patterns or edge cases, make them known.
SQLfiddle demo

I have checked your code it is working fine it is showing 10 in both cases maybe you need to look into you logic.
DECLARE #FiscalMonth varchar(MAX) ='[Dim Date].[Fiscal].[Fiscal Month Number].&[10]&[2014]&[4]&[1]'
DECLARE #FiscalMonthNumber nvarchar(max) = cast(substring(right(#FiscalMonth,18),1,2) as nvarchar(max))
SELECT #FiscalMonthNumber
DECLARE #FiscalMonth1 As varchar(MAX) ='[Dim Date].[Fiscal].[Fiscal Month Number].&[10]&[2014]&[4]&[1]'
DECLARE #FiscalMonthNumber1 AS nvarchar(max) = cast(substring(right(#FiscalMonth,18),1,2) as nvarchar(max))
SELECT #FiscalMonthNumber1

Or you can extract all the numbers from you string and then extract the month number from your number string. something like this
DECLARE #FiscalMonth1 As varchar(MAX) ='[Dim Date].[Fiscal].[Fiscal Month Number].&[10]&[2014]&[4]&[1]'
WHILE PATINDEX('%[^0-9]%',#FiscalMonth1) <> 0
SET #FiscalMonth1 = STUFF(#FiscalMonth1,PATINDEX('%[^0-9]%',#FiscalMonth1),1,'')
SELECT LEFT(#FiscalMonth1, 2)

Related

Remove characters before the last blank, convert result to DATE from NVARCHAR

I receive an Excel spreadsheet monthly with a cell containing both comments and a date in the same cell. I import the spreadsheet to a SQL table and need to extract the last 8-10 characters (the date) and convert them from NVARCHAR to DATE format.
Example:
From this: Active/No Address 4/11/2016
To this: 2016/04/11
The biggest challenge I'm having is that the numbers representing the month and date are not fixed length, they could be either one or two characters. Single character days or months do not have a leading zero.
I have tried every combination of CHARINDEX, RIGHT(), LEFT(), REPLACE, and SUBSTRING I could think of without any success.
Assistance with this would be greatly appreciated.
The method I would go with is reversing the string, finding the first space, and then formatting that chunk of text. This code works for multiple cases with single value months and days and it will not be impacted by the length of the text before the date.
Declare #1 VARCHAR(50) = 'Active/No Address 4/11/2016'
Declare #2 VARCHAR(50) = 'Active/No Address 9/3/2016'
Declare #3 VARCHAR(50) = 'Active/No Address 12/31/2016'
SELECT
REPLACE(CONVERT(DATE, RIGHT(#1,CHARINDEX(' ',REVERSE(#1),0)), 110), '-','/')
, REPLACE(CONVERT(DATE, RIGHT(#2,CHARINDEX(' ',REVERSE(#2),0)), 110), '-','/')
, REPLACE(CONVERT(DATE, RIGHT(#3,CHARINDEX(' ',REVERSE(#3),0)), 110), '-','/')
Like this?
declare #text nvarchar(max) = 'Active/No Address 4/11/2016';
declare #index int = charindex(' ', reverse(#text)) - 2;
declare #foo nvarchar(max) = substring(#text, len(#text) - #index, #index + 1);
select convert(datetime, #foo, 101)

Format a numeric field as text with fixed pattern sql server 2008

I have a numeric field (field1) that has numeric values 1.2, 23.72, 14.02 etc.
I need to present this as a fixed text field format 13 characters as 000000000.000 e.g. 23.72 must display 000000023.720 (9 digits with 3 decimals)Server 2008
What is the best way to do this ?
You can use the following query:
SELECT FORMAT(ColumnName, '000000000.000') FROM TableName
I'm not saying this is the best way, as the final presentation layer (your webpage) might still render it as a numeric value that will follow the format defined on that layer.
You can use FORMAT(#input, '000000000.000') but that won't give you intended output for longer numbers.
You can make your own function which pads zeros ahead and otherwise stops your execution in case of longer numbers.
DECLARE #input NUMERIC(20,7);
DECLARE #number NUMERIC(12,3);
DECLARE #output VARCHAR(13)
SET #input = 123620;
SET #number = CONVERT(NUMERIC(12,3), #input)
SET #output = CONVERT(CHAR(13), #number)
SET #output = REPLICATE('0', 10 - CHARINDEX('.',#output)) + #output
try this,
Declare #i float=23.72
declare #j decimal(18,3)=#i
select #j
select replicate('0',13-len(#j))+cast(#j as varchar)
and tell that for which data it do not work.
Or try this one
SELECT LEFT(RIGHT(REPLICATE('0',12) + CAST('23.72' AS VARCHAR(10)),12) + REPLICATE('0',3),13)
output
000000023.720

Extract a number after a number pattern in SQL

I am working in SQL server. I have some number like 130-0029. I need to get the integer after the - delimiter out of it. So in this example I need to return 29. These are the following scenarios I have with this,
The pattern may differ like 130-00000029 or 130-0029.
If there are all 0's then print 0, else get actual number like 29.
Please advise/suggest me on this.
Here is an example:
declare #s varchar(100) = '130-0029'
select cast(substring(#s, patindex('%[-]%', #s) + 1, len(#s)) as int)
You may need to cast to some numeric if the number overflows ineteger type.
Try this:
DECLARE #num varchar(50) = '130-0029'
SELECT CAST(SUBSTRING(#num, CHARINDEX('-', #num) + 1, LEN(#num)) AS INT)
Here is a fiddle.
This also works if the - is missing. But if what follows is not a number it will give an error.
declare #string as varchar(100)
set #string = '130-0029'
select convert(int,Right(#string, LEN(#string)-CHARINDEX('-', #string)))
Probably not so different than other answers, but this works using STUFF too:
DECLARE #String VARCHAR(10) = '130-0029';
SELECT CONVERT(INT, STUFF(#String, 1, CHARINDEX('-', #String), ''));
See this running in Query Stack Exchange.

Get substring of text in SQL Server

Please help me get the substring of the following text.
I would like to be able to extract the text
PilotCube_2Year
FROM
/content/folder[#name=&apos;Reporting Packages&apos;]/package[#name=&apos;PiotCube_2Year&apos;]
I am using SQL Server 2008
I have tried substring and Charindex but could not really get the string PilotCube_2Year
Assuming package[#name= is what tells you where the string you are looking for is, you could try something like this:
DECLARE #toSearch AS VARCHAR(100) = '/content/folder[#name=''Reporting Packages'']/package[#name=''PiotCube_2Year'']'
DECLARE #toFind AS VARCHAR(100) = 'package[#name='
DECLARE #start AS INT = CHARINDEX(#toFind , #toSearch ) + LEN(#toFind) + 1
SELECT SUBSTRING(#toSearch, --expression
#start, --start
CHARINDEX(']' , #toSearch, #start) - #start - 1) --length
Result
PiotCube_2Year

SQL convert int to time

I have a database that displays time as an integer. However I am wanting to output this into a report with the correct format. This is the format that I would like to change:
eg.
183000 would become 18:30
500 would become 00:05
160000 would become 16:00
and so on.
I have had a look and CAST and CONVERT but not successfully managed to get this the time in the correct format.
Assuming your input will always be an int, you can parse it with something like:
DECLARE #stringTime varchar(6)
SET #stringTime = RIGHT('000000' + CAST(intTime AS VARCHAR), 6)
SELECT CAST(LEFT(#stringTime, 2) + ':' + RIGHT(LEFT(#stringTime, 4), 2) AS TIME) as TimeValue
I'd DEFINITELY look to change this field to an actual time or datetime field, as this level of conversion is not advised, especially for a heavily used database. There's just really got to be a better way to store your data.
Using an int value this way allows for a lot of bad data, without adding a lot of additional checks and/or constraints on your inputs (i.e.: 260000, 127900, etc.)
looks like you need to divide by 100 to get the seconds, divide by 10000 to get the minutes, and divide by 1000000 to get the hours, then format those values as a string, inserting a colon between hours and minutes, like
hh:mm
First cast to a varchar field and convert all times to 4 digits adding leading zeros if need be (500 would become 0500)and then break up the field with concantenation Left(myfield,2) + ':' + right(myfield,2)
This is something stupid to do every time you run a report, it is wasteful of server resources. If possible change the field to varchar and runthe code once. If not possible, can you add a formatted field and have a trigger do the formatiing on insertion (you'll still need to update the field the first time? Possibly a constraint would do instead of a trigger, but that would depend on the database.
I'm assuming that you are on SQL Server based on use of CONVERT and your previous questions.
You could use DATEADD for this too.
WITH Times AS
(
SELECT 183000 AS T
UNION ALL
SELECT 500
UNION ALL
SELECT 160000
)
SELECT CAST(DATEADD(SECOND, T%100 + (60*(T%10000 / 100)) + 3600*(T/10000),0)
AS time /*Or datetime if < SQL Server 2008*/)
FROM Times
declare #i int = 235959
select cast(stuff(stuff(
case when len(cast(#i as varchar(6))) = 6 then cast(#i as varchar(6))
else REPLICATE('0',6 - LEN(cast(#i as varchar(6))))+cast(#i as varchar(6))
end
,3,0,':'), 6, 0,':') as datetime)
set #i = 500
select cast(stuff(stuff(
case when len(cast(#i as varchar(6))) = 6 then cast(#i as varchar(6))
else REPLICATE('0',6 - LEN(cast(#i as varchar(6))))+cast(#i as varchar(6))
end
,3,0,':'), 6, 0,':') as datetime)
DECLARE #intTime int
SET #intTime = 50000
SELECT CAST(STUFF(STUFF(CONCAT(REPLICATE('0', 6 - LEN(#intTime)),#intTime),3,0,':'),6,0,':') AS TIME(0))
ALTER FUNCTION [dbo].[MinutesToDuration]
(
#minutes int
)
RETURNS nvarchar(30)
AS
BEGIN
declare #hours nvarchar(20)
DECLARE #XX NVARCHAR(10)
DECLARE #HH VARCHAR(2)
DECLARE #TT VARCHAR(2)
DECLARE #BL NVARCHAR(2)
DECLARE #TM VARCHAR(5)
SET #XX=#minutes
IF #XX<60
BEGIN
IF #XX<10
BEGIN
SET #HH='00'
SET #TT='0'+#XX
END
ELSE
BEGIN
SET #HH='00'
SET #TT=#XX
END
END
ELSE
BEGIN
IF #XX%60=0
BEGIN
SET #HH=#XX/60
SET #TT='00'
END
ELSE
BEGIN
SET #BL= #XX%60
IF #BL<10
BEGIN
SET #HH=#XX/60
SET #TT='0'+#BL
END
ELSE
BEGIN
SET #HH=#XX/60
SET #TT=#BL
END
END
END
SET #hours= #HH+':'+#TT
return #hours
END

Resources