Concatenation not working inside of function in SQL Server - sql

I am converting minutes to days and hours. When I am using following code, it works fine
declare #theMinutes int
Set #theMinutes = 1449
select cast(#theMinutes / 1440 as varchar)
+ ' Day(s) '+ cast((#theMinutes % 1440 / 60) as varchar)
+ ' Hour(s) '+ cast(#theMinutes % 60 as varchar)
+ ' Minute(s)' AS COLUMN_A
and displays result
1 Day(s) 0 Hour(s) 9 Minute(s)
But when I use this to write a function, then it is only returning 1, the rest things are not getting concatenated
Create function [dbo].[ConvertMinToDays]
(
#theMinutes int
)
RETURNS varchar
AS
BEGIN
Declare #convertedStr varchar(200)
SET #convertedStr = cast(#theMinutes / 1440 as varchar(10)) + ' Day(s) '
+ cast((#theMinutes % 1440 / 60) as varchar(10))+ ' Hour(s) '
+ cast(#theMinutes % 60 as varchar(10)) + ' Minute(s)';
return #convertedStr;
END
GO
SELECT dbo.ConvertMinToDays(1449) as COLUMN_A
Can Anybody help me , where i am going wrong ??

Change
RETURNS varchar
to
RETURNS varchar(200)
I'm assuming its only going to return one character otherwise

You are returning a varchar
Change it to
RETURNS varchar(200)

Related

SQL Server formatting negative values from selected data

I am new to stackoverflow but I do search it often.
I am creating a report from data in which I have to format negative numbers like,
-00000010 (9 characters max)
I am getting this,
000000-10
This is what I am attempting now but I'm having issues. Any help would be greatly appreciated.
SELECT 'H'
+ DG.BLOCK
+ LEFT(DG.ZIP,5)
+ RIGHT('000000000'
+ CAST(CAST(SUM(DG.WP)AS INT) AS VARCHAR(9)),9)
+ RIGHT('000000000' + CAST(CAST(SUM(DG.WE)AS INT) AS VARCHAR(9)),9)
+ RIGHT('000000000' + CAST(CAST(SUM(DG.EP)AS INT) AS VARCHAR(9)),9)
+ RIGHT('000000000' + CAST(CAST(SUM(DG.EE)AS INT) AS VARCHAR(9)),9)
+ RIGHT('000000000' + CAST(CAST(COUNT(DGG.CLAIMCONTROL)AS INT) AS VARCHAR(9)),9)
+ RIGHT('000000000' + CAST(CAST(SUM(DGG.INC) AS INT) AS VARCHAR(9)),9)
+ RIGHT('000000000' + CAST(CAST(SUM(DGG.PAID)AS INT) AS VARCHAR(9)),9)
+ RIGHT('000000000' + CAST(CAST(SUM(DGG.ALAE) AS INT) AS VARCHAR(9)),9)
AS [H Record]
FROM TABLE
If 2012+, you have the option of Format().
Example
Select replace(format(-1,' 000000000'),'- ','-')
Returns
-000000001 If number was negative
000000001 If number was positive
Just a word of caution. Format() has some great functionality, but is not known to be a high performer.
The following code demonstrates formatting the data as either 9 digits plus an optional sign or as a fixed 9 characters including the sign.
-- Sample data.
declare #Samples as Table ( Sample Int );
insert into #Samples ( Sample ) values ( 0 ), ( 1 ), ( -10 ), ( 100 ), ( -1000 );
-- Format the data.
select Sample,
case when Sign( Sample ) = -1 then '-' else '' end +
Right( Replicate( '0', 8 ) + Cast( Abs( Sample ) as VarChar(9) ), 9 ) as FormattedSample9PlusSign,
case when Sign( Sample ) = -1 then
'-' + Right( Replicate( '0', 7 ) + Cast( -Sample as VarChar(8) ), 8 ) else
Right( Replicate( '0', 8 ) + Cast( Sample as VarChar(9) ), 9 ) end as FormattedSample9
from #Samples;
Tip: In SSMS use query results to text (Ctrl-T) for more convenient display.
You can try this, if you do not have v2012+:
DECLARE #mockup TABLE(SomeNumber INT);
DECLARE #padWidth INT=3;
INSERT INTO #mockup VALUES(-1000),(-500),(-1),(0),(1),(500),(1000);
SELECT CASE WHEN m.SomeNumber < 0 THEN '-' ELSE ' ' END
+ REPLACE(STR(ABS(m.SomeNumber),#padWidth),' ','0')
FROM #mockup AS m;
Numbers, which are to big, will be returned as ***. This is better than other approaches cutting the string with RIGHT or LEFT. They might return a bad result...
This is returned
-***
-500
-001
000
001
500
***
In DB2 this works to get a number of 15 digits including the sign:
CASE WHEN MYNUMBER < 0 THEN '-' || LPAD(MYNUMBER , 14, 0)
ELSE LPAD(MYNUMBER , 15, 0)
END

sql combining two columns one of which is a datetime

I have the following sql code (ms sql server 2008)
select (analysisno + ' ' + '-' + ' ' + description + ' ' + '-' + ' ' + formdate) as columnA
from Old_Analysis_Data
order by formdate
I get the following error Conversion failed when converting date and/or time from character string.
AnalysisNo is a varchar(10)
description is a varchar(500)
formdate is a datetime
(not my table, its an old one)
Any ideas, as cant find an answer on google.
Convert the time to a string using Convert before concatenation:
SELECT ( analysisno + ' ' + '-' + ' ' + description + ' ' + '-' + ' '
+ CONVERT(VARCHAR(20), formdate, 100) ) AS columnA
FROM
Old_Analysis_Data
ORDER BY
formdate
In this case, 100 is a style that sets datestamp format to mon dd yyyy hh:miAM (or PM) as an example
See http://www.w3schools.com/sql/func_convert.asp
Try this:
select (analysisno + ' - ' + description + ' - '
+ convert(varchar(100),formdate)) as columnA
from Old_Analysis_Data order by formdate
Instead of concatenating formdate directly, convert it to string first,
convert(varchar(15), formdate, 103)
which gives you the following format
dd/MM/yyyy

TSQL round number and check in which group it is

I have a quite simple task:
I must check in wchich group my float is.
Here are my groups:
0-30 display "(0-30)"
30-40 display "(0-30)"
40-50 display "(0-30)"
50-60 display "(0-30)"
etc
I have created a simple script:
DECLARE #num FLOAT
SET #num = 42.5;
SELECT CASE WHEN #num<=30 THEN '(0-30)'
ELSE '('+convert(VARCHAR,convert(INT,round((#num/10),0))*10)+'-'+convert(VARCHAR,convert(INT,round(((#num+10)/10),0))*10)+')'
END
I think it is a little lame, so if anyone could help me out with creating a better solution :)
Thanks for any advice :)
Use:
DECLARE #num FLOAT
SET #num = 311.2;
SELECT
CASE
WHEN #num <= 30
THEN '(0-30)'
ELSE '(' + cast(cast(#num AS INT) / 10 * 10 AS VARCHAR) + '-' + cast(cast(#num AS INT) / 10 * 10 + 10 AS VARCHAR) + ')' END
Or you can use: (to get rid of the CASE statement and get a more readable look, IMO)
declare #num float = 156
select
'(' + convert(varchar, lowLimit) + ' - ' + convert(varchar, highLimit) + ')'
from
(
select
0 as lowLimit,
30 as highLimit
where
#num <= 30
union all
select
floor(#num/10)*10,
ceiling(#num/10)*10
where
#num > 30
) limits

how to parse for more than 4 positions

I have a funny case where a piece of data needed, is actually embedded in a column of data looking something like this:
note that is a shop with strong legacy mess still in place.
adlu201008270919_3.zip the date is what i need and is embedded.
I have code to do this here:
AND CAST(SUBSTRING(M.MDS_FILE,5,4) + '-' + SUBSTRING(M.MDS_FILE,9,2) + '-' + SUBSTRING(M.MDS_FILE,11,2) as datetime)
But now I find out that where you have here 'adlu' that is 4 pos. It can be 3 or 2 or 1.
So I have to code for that I have come up with this: but it's not compiling:
AND CASE WHEN WHEN CAST(SUBSTRING(M.MDS_FILE,5,4) + '-' + SUBSTRING(M.MDS_FILE,9,2) + '-' + SUBSTRING(M.MDS_FILE,11,2) as datetime)
ELSE WHEN OEN.LENGTH(S.FACILITY_KEY) = 3 THEN CAST(SUBSTRING(M.MDS_FILE,4,4) + '-' + SUBSTRING(M.MDS_FILE,8,2) + '-' + SUBSTRING(M.MDS_FILE,10,2) as datetime)
ELSE WHEN OEN.LENGTH(S.FACILITY_KEY) = 2 THEN CAST(SUBSTRING(M.MDS_FILE,3,4) + '-' + SUBSTRING(M.MDS_FILE,7,2) + '-' + SUBSTRING(M.MDS_FILE,9,2) as datetime)
ELSE CAST(SUBSTRING(M.MDS_FILE,2,4) + '-' + SUBSTRING(M.MDS_FILE,6,2) + '-' + SUBSTRING(M.MDS_FILE,8,2) as datetime) END
CASE requires an evaluation. Your first statement just says WHEN(a bunch of conversions) but there's never an evaluation (=, <, > etc).
I'm assuming you want that to be AND CASE WHEN OEN.LENGTH(s.FACILITY_KEY) = 4 THEN ...
Instead of a CASE statement based of S.FACILITY_KEY, I would use PATINDEX to dynamically find the start position of the date string that you're looking for:
DECLARE
#TestValue1 VARCHAR(50),
#TestValue2 VARCHAR(50),
#TestValue3 VARCHAR(50),
#TestValue4 VARCHAR(50)
SET #TestValue1 = 'adlu201008270919_3.zip'
SET #TestValue2 = 'adl201008270919_3.zip'
SET #TestValue3 = 'ad201008270919_3.zip'
SET #TestValue4 = 'a201008270919_3.zip'
SELECT CAST(SUBSTRING(#TestValue1, PATINDEX('%[1-2][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', #TestValue1), 8) AS DATETIME)
SELECT CAST(SUBSTRING(#TestValue2, PATINDEX('%[1-2][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', #TestValue2), 8) AS DATETIME)
SELECT CAST(SUBSTRING(#TestValue3, PATINDEX('%[1-2][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', #TestValue3), 8) AS DATETIME)
SELECT CAST(SUBSTRING(#TestValue4, PATINDEX('%[1-2][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', #TestValue4), 8) AS DATETIME)

How to display the number “12” in the format of “0000012”

How to display the number “12” in the format of “0000012” Using SQL
if you just want the number 12 then
SELECT '0000012'
else if it is a number you need to display with 7 digits:
SELECT RIGHT('0000000'+CONVERT(nvarchar,FieldValue),7)
More info on the question would help.
How about something like
DECLARE #Val INT
DECLARE #Length INT
SELECT #Val = 12,
#Length = 7
SELECT REPLICATE('0',#Length - LEN(CAST(#Val AS VARCHAR(MAX)))) + CAST(#Val AS VARCHAR(MAX))
REPLICATE (Transact-SQL)
Repeats a string value a specified
number of times.
The shortest answer that probably also works best is just
SELECT RIGHT(10000000+ #Val, #Length)
e.g.
SELECT RIGHT(10000000+ NumColumn, 7)
I haven't got a server to test with, but you should be able to use the following in your SQL:
'RN ' + RIGHT(CAST(auto_id AS VarChar) + '000000', 6)
eg:
Code:
SELECT 'RN ' + RIGHT(CAST(auto_id AS VarChar) + '000000', 6)
FROM tablename
This is not efficient but will work for your case -
DECLARE #num int
DECLARE #totalChar int
SET #num = 12
SET #totalChar = 10
SELECT right('0000000000' + CONVERT(varchar, #num), #totalChar)
Output -
000000012
This should easily port to other SQLs:
SELECT
REVERSE(CAST(REVERSE(CAST(CAST(12 AS INTEGER) AS VARCHAR(7))) + '000000' AS CHAR(7)))
SELECT REPLACE(STR(12, 7), ' ', '0')