Get the right number of a value in SQL Server using substring - sql-server

I have this data in my SQL Server:
1/2
1/4
2/23
12/13
1/10
...
I need to change these to 002,004,023,013,010,..
I just need to select the end (RIGHT) part number of my value. I got the LEFT part using this code before:
RIGHT('000' + LEFT(SheetNumber, CHARINDEX('/', SheetNumber) - 1), 3)

Try this,
SELECT Right('000' + RIGHT(SheetNumber,LEN(SheetNumber) - CHARINDEX('/',SheetNumber) ), 3)
OR
SELECT RIGHT(REPLACE(#SheetNumber,'/','/000'),3)

Your were almost there
Declare #YourTable table (SheetNumber varchar(50))
Insert Into #YourTable values
('1/2'),
('1/4'),
('2/23'),
('12/13'),
('1/10')
Select right('000'+substring(SheetNumber,CHARINDEX('/',SheetNumber) + 1,10),3)
From #YourTable
Returns
(No column name)
002
004
023
013
010

First you need to get the right part like this :
declare #table table (SheetNumber varchar(10))
insert into #table values ('1/2')
insert into #table values ('2/23')
select Right(SheetNumber, len(SheetNumber) - CHARINDEX('/',SheetNumber)) from #table
This will give you this :
2
23
Now build on this to pad 0 in front of it
declare #table table (SheetNumber varchar(10))
insert into #table values ('1/2')
insert into #table values ('2/23')
select Right('000' + Right(SheetNumber, len(SheetNumber) - CHARINDEX('/',SheetNumber)), 3) from #table
and that will give you this :
002
023

Related

How to convert varchar to time hh:mm

I have varchars representing military times:
a 2130 -- 21 hours
b 103 -- 1 hour
c 10 -- 10 minutes
d 1 -- 1 minutes
the left two characters always represent minutes. In example c and c above 10 and 1 are always minutes. example b 103 has three characters. 1 is hour 03 is minute in this case.
How do I convert this into time hh:mm format?
One option is use to use Format()
Example
Declare #YourTable table (SomeCol int)
Insert into #YourTable values
(2130)
,(103)
,(10)
,(1)
Select SomeCol
,TimeValue = format(SomeCol,'00:00')
From #YourTable
Returns
SomeCol TimeValue
2130 21:30
103 01:03
10 00:10
1 00:01
EDIT - Requested EDIT for 2008
Declare #YourTable table (SomeCol int)
Insert into #YourTable values
(2130)
,(103)
,(10)
,(1)
Select SomeCol
,TimeValue = stuff(right('0000' + left(SomeCol, 4),4), 3, 0, ':')
From #YourTable
You can try the following using length of column value and case statement.
Declare #YourTable table (SomeCol int)
Insert into #YourTable values
(2130)
,(103)
,(10)
,(1)
Select
case LEN(SomeCol)
when 4 then SUBSTRING('2130', 1, 2) + ':' + SUBSTRING('2130', 3, 2)
when 3 then '0' + SUBSTRING('103', 1, 1) + ':' + SUBSTRING('103', 2, 2)
when 2 then '00:' + CONVERT(Varchar(5), SomeCol)
else '00:0' + CONVERT(Varchar(5), SomeCol)
end as TimeValue
from #YourTable
Good day Jacob,
Please check if this solution fit you:
Declare #YourTable table (SomeCol int)
Insert into #YourTable values
(2130)
,(103)
,(10)
,(1)
--Select SomeCol,TimeValue = format(SomeCol,'00:00'), SQL_VARIANT_PROPERTY (format(SomeCol,'00:00'),'BaseType')
--From #YourTable
SELECT CONVERT(TIME(0),TIMEFROMPARTS(ROUND(SomeCol/100,0), SomeCol%100,0,0,0))
FROM #YourTable
Ops, I notice new information in the comments. Seems like you use SQL Server 2008R2 and TIMEFROMPARTS will not work on SQL Server2008r2 (only starting with 2012)...I will edit the answer in a second
Note! I highly recommend to re-think about your database design.Please read the comment I wrote above for more information
Update:
-- For old servers please check if one of these this fit you
SELECT --RIGHT('00' + CONVERT(VARCHAR(2),ROUND(SomeCol/100,0)),2),RIGHT('00' + CONVERT(VARCHAR(2),SomeCol%100),2),
CONVERT(TIME(0),RIGHT('00' + CONVERT(VARCHAR(2),ROUND(SomeCol/100,0)),2) + ':' + RIGHT('00' + CONVERT(VARCHAR(2),SomeCol%100),2))
FROM #YourTable

Select statement with unique format in SQL Server

I have a table with a column 'Number' which contain values like INV-00100,INV-00101,INV-00102,INV-00103 etc.
I want to get highest value +1 in a format like "INV-00103". How it possible?
Any suggestions??
I have tried this query
SELECT
ISNULL(MAX(CAST(SUBSTRING(Number, 5, LEN(Number) - 4) AS INT)), 0) AS [MaxNo]
FROM
Table
But this statement returns like "103" as result. I want to get this "103" as "00103" (total of 5 digits).
Try like follwoing.
DECLARE #TABLE TABLE(Code VARCHAR(100))
INSERT INTO #TABLE
VALUES ('INV-00100'),('INV-00101'),('INV-00102')
SELECT RIGHT('00000'+
CAST(MAX(TRY_PARSE(SUBSTRING(Code,CHARINDEX('-',Code)+1,
LEN(Code)-CHARINDEX('-',Code)) AS INT) + 1) AS VARCHAR(10)),5)
FROM #TABLE
Output
00103
Edit:
This is working fine.. But what will happen if the Number exceeds
99999?? Will this give a value like INV-100000 – Vahid
DECLARE #TABLE TABLE(Code VARCHAR(100))
INSERT INTO #TABLE
VALUES ('INV-00100'),('INV-00101'),('INV-00102')
SELECT
(
CASE WHEN [Output] > 99999 THEN CAST([Output] AS VARCHAR(100))
--MORE CONDITION
ELSE RIGHT('00000'+CAST([Output] AS VARCHAR(100)),5)
END
) AS [Output]
FROM
(
SELECT
MAX(TRY_PARSE(SUBSTRING(Code,CHARINDEX('-',Code)+1,
LEN(Code)-CHARINDEX('-',Code)) AS INT) + 1) AS [Output]
FROM #TABLE
) T
What about something like this?
select left('INV-00100',6) + cast(max(cast(right('INV-00100', 5) as int) + 1)as VARCHAR)

Insert Substring Values into SQL Temp Table Using While Loop?

I have a table called accountNumbers. An example of values in the table are:
01-005-000-000-001-000
01-005-311-097-000
001-005-105-545
What I want to do is split the column (accountNum) at the dash, and then insert that value into a temp table, #test. When printing out #test, it should look like:
01
005
000
001
311
097
and so on. I cannot use store procedures or functions. I can get the first value, but any while loop I try just prints that first row over and over again.
WHILE ##ROWCOUNT > (select count(*) from dbo.accountNumbers
BEGIN
insert into #test (split, accountNum)
select SUBSTRING(accountNum, 1, CHARINDEX('-', accountNum) -1), accountNum
from dbo.accountNumbers
END
The restriction of no functions or procedures seems a little strange but you don't have to use a function to do this. A VERY minor tweak to the XML function found here http://sqlperformance.com/2012/07/t-sql-queries/split-strings can be utilized so you don't need a function to do this.
if OBJECT_ID('tempdb..#something') is not null
drop table #something
create table #something
(
AccountNumbers varchar(100)
)
insert #something
select '01-005-000-000-001-000' union all
select '01-005-311-097-000' union all
select '001-005-105-545'
select *
from #something s
cross apply
(
SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(s.AccountNumbers, '-', '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
)MySplit

How to call a recursive function in sql server

I have a table as follows
cat_id Cat_Name Main_Cat_Id
1 veg null
2 main course 1
3 starter 1
4 Indian 2
5 mexican 2
6 tahi 3
7 chinese 3
8 nonveg null
9 main course 8
10 indian 9
11 starter 8
12 tahi 11
13 chinese 11
(Main_Cat_Id is cat_id of previously added category in which it belongs)
This table is used for the categories the product where veg category has the two sub category main course and starter which is identify by main_cat_id
and those subcategories again has sub category as indian and mexican
And this categorization is dependent on the user; he can add more sub categories to indian, mexican also so that he can have any level of categorization
now I have to select all the subcategories of any node like if I take veg i have to select
(1)veg > (2)main course(1) > (4)indian(2)
> (5)mexican(2)
> (3)starter(1) > (6)thai(3)
> (7)chinese(3)
to form the string as 1,2,4,5,3,6,7
to do this i wrote a sql function as
CREATE FUNCTION [dbo].[GetSubCategory_TEST]
( #MainCategory int, #Category varchar(max))
RETURNS varchar(max)
AS
BEGIN
IF EXISTS (SELECT Cat_Id FROM Category WHERE Main_Cat_Id=#MainCategory)
BEGIN
DECLARE #TEMP TABLE
(
CAT_ID INT
)
INSERT INTO #TEMP(CAT_ID) SELECT Cat_Id FROM Category WHERE Main_Cat_Id=#MainCategory
DECLARE #TEMP_CAT_ID INT
DECLARE CUR_CAT_ID CURSOR FOR SELECT CAT_ID FROM #TEMP
OPEN CUR_CAT_ID
WHILE 1 =1
BEGIN
FETCH NEXT FROM CUR_CAT_ID
INTO #TEMP_CAT_ID;
IF ##FETCH_STATUS <> 0
SET #Category=#Category+','+ CONVERT(VARCHAR(50), #TEMP_CAT_ID)
SET #Category = [dbo].[GetSubCategory](#TEMP_CAT_ID,#Category)
END
CLOSE CUR_CAT_ID
DEALLOCATE CUR_CAT_ID
END
return #Category
END
but this function keep on executing and not gives the desired output i don't understands what wrong is going on plz help me to get this
You dont need a recursive function to build this, you can use a Recursive CTE for that.
Something like
DECLARE #TABLE TABLE(
cat_id INT,
Cat_Name VARCHAR(50),
Main_Cat_Id INT
)
INSERT INTO #TABLE SELECT 1,'veg',null
INSERT INTO #TABLE SELECT 2,'main course',1
INSERT INTO #TABLE SELECT 3,'starter',1
INSERT INTO #TABLE SELECT 4,'Indian',2
INSERT INTO #TABLE SELECT 5,'mexican',2
INSERT INTO #TABLE SELECT 6,'tahi',3
INSERT INTO #TABLE SELECT 7,'chinese',3
INSERT INTO #TABLE SELECT 8,'nonveg',null
INSERT INTO #TABLE SELECT 9,'main course',8
INSERT INTO #TABLE SELECT 10,'indian',9
INSERT INTO #TABLE SELECT 11,'starter',8
INSERT INTO #TABLE SELECT 12,'tahi',11
INSERT INTO #TABLE SELECT 13,'chinese',11
;WITH Recursives AS (
SELECT *,
CAST(cat_id AS VARCHAR(MAX)) + '\' ID_Path
FROM #TABLE
WHERE Main_Cat_Id IS NULL
UNION ALL
SELECT t.*,
r.ID_Path + CAST(t.cat_id AS VARCHAR(MAX)) + '\'
FROM #TABLE t INNER JOIN
Recursives r ON t.Main_Cat_Id = r.cat_id
)
SELECT *
FROM Recursives
I am ashamed, but I used #astander scipt to give string result.
First I created data you gave.
Second I collect rows which I need
And then using XML I put everything in one row (function STUFF removes first comma)
DECLARE #TABLE TABLE(
cat_id INT,
Cat_Name VARCHAR(50),
Main_Cat_Id INT
)
DECLARE #Collected TABLE(
cat_id INT
)
INSERT INTO #TABLE SELECT 1,'veg',null
INSERT INTO #TABLE SELECT 2,'main course',1
INSERT INTO #TABLE SELECT 3,'starter',1
INSERT INTO #TABLE SELECT 4,'Indian',2
INSERT INTO #TABLE SELECT 5,'mexican',2
INSERT INTO #TABLE SELECT 6,'tahi',3
INSERT INTO #TABLE SELECT 7,'chinese',3
INSERT INTO #TABLE SELECT 8,'nonveg',null
INSERT INTO #TABLE SELECT 9,'main course',8
INSERT INTO #TABLE SELECT 10,'indian',9
INSERT INTO #TABLE SELECT 11,'starter',8
INSERT INTO #TABLE SELECT 12,'tahi',11
INSERT INTO #TABLE SELECT 13,'chinese',11
INSERT INTO #TABLE SELECT 14,'chinese',6
DECLARE #nodeID INT = 1;
DECLARE #result VARCHAR(MAX);
;WITH Recursives AS (
SELECT cat_id, main_cat_id
FROM #TABLE
WHERE Cat_Id = #nodeID
UNION ALL
SELECT T.cat_id, T.main_cat_id
FROM #TABLE AS T
INNER JOIN Recursives AS R
ON t.Main_Cat_Id = r.cat_id
)
INSERT INTO #Collected
SELECT cat_id
FROM Recursives
SELECT #result = STUFF(
(SELECT ',' + CAST( cat_id AS VARCHAR)
FROM #Collected
ORDER BY cat_id
FOR XML PATH('')
), 1,1,'')
SELECT #result
Your cursor is looping infinitely because you asked it to keep going until 1 no longer equals 1:
WHILE 1 =1
1=1 is always true so the loop never ends, and you don't explicitly break out of it anywhere.
You would do well to study some examples of cursors, for example this one in the Microsoft T-SQL documentation. They are quite formulaic and the main syntax rarely needs to vary much.
The standard approach after opening the cursor is to do an initial fetch next to get the first result, then open a while loop conditional on ##FETCH_STATUS = 0 (0 meaning successful).
Because you're looking only for unsuccessful cursor fetch states inside your cursor:
IF ##FETCH_STATUS <> 0
The setting of #Category will only happen once the cursor has gone past the last row in the set. I suspect this is exactly what you don't want.
I'm also not sure about the scoping of the #Category variable, since it's an input parameter to the function; I generally create new variables inside a function to work with, but off the top of my head I'm not sure this will actually create a problem or not.
More generally, although I don't totally understand what you're trying to achieve here, a recursive function involving a cursor is probably not the right way to do it, as Adriaan Stander's answer suggests.

Converting an integer to a 0-padded string

In SQL Server 2008, I want to represent an integer as a 3-character string - so:
3 becomes '003'
5 becomes '005'
107 becomes '107'
How can I do this?
/* Method 1 Using RIGHT function */
SELECT RIGHT('000' + CAST(NumericColumn AS VARCHAR(3)), 3) PaddedCnumericColumn
FROM MyTable
/* Method 2 Using RIGHT AND REPLICATE function */
SELECT RIGHT(REPLICATE('0', 3) + CAST(NumericColumn AS VARCHAR(3)), 3) PaddedCnumericColumn
FROM MyTable
You can try this
DECLARE #Table TABLE(
Val INT
)
INSERT INTO #Table (Val) SELECT 1
INSERT INTO #Table (Val) SELECT 10
INSERT INTO #Table (Val) SELECT 100
SELECT REPLICATE('0',3 - LEN(CAST(Val AS VARCHAR(3)))) + CAST(Val AS VARCHAR(3))
FROM #Table
WHERE ABS(Val) < 1000

Resources