Unique 8 digit incremental number - sql

I'm trying to generate a number which will ultimately be stored as string(varchar). e.g.
First - ABC00000001
Second- ABC00000002
.........................
I am able to generate character string as expected. Now the problem is,incremental number.
What i am trying to do is get the last number stored e.g. ABC00000009 and generate the next number that is ABC00000010. How to do the same?
If i extract integers from this than i will get 1 or 10,how to make it according to 8 digit format.
Any help would really be appreciated.

Of course if changing the table structure is not an option, you can try this:
DECLARE #lastValue VARCHAR(15) = 'ABC00000001'
SELECT CONCAT('ABC', RIGHT(100000000 + CAST(RIGHT(#lastValue, 8) AS INT) + 1, 8))
Result
-----------
ABC00000002

I would suggest that you create an identity column. This will increment (usually by 1, but not always). Then create a computed column:
alter table t add generated_number as
('ABC' + right(replicate('0', 8) + cast(idcol as varchar(255)), 8));

Almost the same approach Gordon Linoff has taken, I just prefer to use math where possible instead of string concatenation. My answer is different only because I add id value to 100000000 instead of using replicate.
CREATE TABLE dbo.test (
id int IDENTITY(1, 1) PRIMARY KEY
, some_value sysname UNIQUE
, super_column AS 'ABC' + RIGHT(100000000 + id, 8));
GO
INSERT INTO dbo.test (some_value)
VALUES ('some_value_1'), ('some_value_2');
SELECT *
FROM dbo.test AS T;
Result:
+----+--------------+--------------+
| id | some_value | super_column |
+----+--------------+--------------+
| 1 | some_value_1 | ABC00000001 |
| 2 | some_value_2 | ABC00000002 |
+----+--------------+--------------+

Related

How to use the SQL REPLACE Function, so that it will replace some text between a certain range, rather than one specific value

I have a table called Product and I am trying to replace some of the values in the Product ID column pictured below:
ProductID
PIDLL0000074853
PIDLL000086752
PIDLL00000084276
I am familiar with the REPLACE function and have used this like so:
SELECT REPLACE(ProductID, 'LL00000', '/') AS 'Product Code'
FROM Product
Which returns:
Product Code
PID/74853
PIDLL000086752
PID/084276
There will always be there letter L in the ProductID twice LL. However, the zeros range between 4-6. The L and 0 should be replaced with a /.
If anyone could suggest the best way to achieve this, it would be greatly appreciate. I'm using Microsoft SQL Server, so standard SQL syntax would be ideal.
Please try the following solution.
All credit goes to #JeroenMostert
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (ID INT IDENTITY PRIMARY KEY, ProductID VARCHAR(50));
INSERT INTO #tbl (ProductID) VALUES
('PIDLL0000074853'),
('PIDLL000086752'),
('PIDLL00000084276'),
('PITLL0000084770');
-- DDL and sample data population, end
SELECT *
, CONCAT(LEFT(ProductID,3),'/', CONVERT(DECIMAL(38, 0), STUFF(ProductID, 1, 5, ''))) AS [After]
FROM #tbl;
Output
+----+------------------+-----------+
| ID | ProductID | After |
+----+------------------+-----------+
| 1 | PIDLL0000074853 | PID/74853 |
| 2 | PIDLL000086752 | PID/86752 |
| 3 | PIDLL00000084276 | PID/84276 |
| 4 | PITLL0000084770 | PIT/84770 |
+----+------------------+-----------+
This isn't particularly pretty in T-SQL, as it doesn't support regex or even pattern replacement. Therefore you method is to use things like CHARINDEX and PATINDEX to find the start and end positions and then replace (don't read REPLACE) that part of the text.
This uses CHARINDEX to find the 'LL', and then PATINDEX to find the first non '0' character after that position. As PATINDEX doesn't support a start position I have to use STUFF to remove the first characters.
Then, finally, we can use STUFF (again) to replace the length of characters with a single '/':
SELECT STUFF(V.ProductID,CI.I+2,ISNULL(PI.I,0),'/')
FROM (VALUES('PIDLL0000074853'),
('PIDLL000086752'),
('PIDLL00000084276'),
('PIDLL3246954384276'))V(ProductID)
CROSS APPLY(VALUES(NULLIF(CHARINDEX('LL',V.ProductID),0)))CI(I)
CROSS APPLY(VALUES(NULLIF(PATINDEX('%[^0]%',STUFF(V.ProductID,1,CI.I+2,'')),1)))PI(I);
If you are always starting with "PIDLL", you can just remove the "PIDLL", cast the rest as an INT to lose the leading 0's, then append the front of the string with "PID/". One line of code.
-- Sample Data
DECLARE #t TABLE (ProductID VARCHAR(40));
INSERT #t VALUES('PIDLL0000074853'),('PIDLL000086752'),('PIDLL00000084276');
-- Solution
SELECT t.ProductID, NewProdID = 'PID/'+LEFT(CAST(REPLACE(t.ProductID,'PIDLL','') AS INT),20)
FROM #t AS t;
Returns:
ProductID NewProdID
------------------ ----------------
PIDLL0000074853 PID/74853
PIDLL000086752 PID/86752
PIDLL00000084276 PID/84276

Add Trailing Zeroes After Decimal

I am working with sku numbers that have the following 9 character structure:
a. a 3 digit number,
b. a period,
c. a five digit number.
An example: 505.12345.
A considerable % of the sku's end in 0. Examples: 505.12340, 505.12300, 505.12000.
I had no trouble keeping the trailing zeroes in SQL Server by setting the datatype to varchar after the migration from S3 -> SQL Server. I used a new machine learning model in AWS Sagemaker that cut off the trailing zeroes prior to the migration to S3.
The example sku's above now look like: 505.1234, 505.123, 505.12
My question: what is the best way to add trailing zeroes to all sku's where LEN([sku]) < 9? I would prefer to keep the sku datatype as varchar.
If you have a string, you can right-pad it with 0s as follows:
left(sku + replicate('0', 9), 9)
Alternatively:
sku + replicate('0', 9 - len(sku))
Demo on DB Fiddle:
select sku,
left(sku + replicate('0', 9), 9) new_sku,
sku + replicate('0', 9 - len(sku)) new_sku2
from (values ('505.1234'), ('505.123'), ('505.12'), ('505.12345')) x(sku)
sku | new_sku | new_sku2
:-------- | :-------- | :--------
505.1234 | 505.12340 | 505.12340
505.123 | 505.12300 | 505.12300
505.12 | 505.12000 | 505.12000
505.12345 | 505.12345 | 505.12345
One simple way would be to CAST back to DECIMAL(9, 5) and then CAST again to CHAR(9)
Data
drop table if exists #tTable;
go
create table #tTable(
dec_num varchar(20) not null);
Insert into #tTable values
('505.1234'),
('505.123'),
('505.12');
Query
select cast(cast(dec_num as decimal(9,5)) as char(9)) char_9
from #tTable;
Output
char_9
505.12340
505.12300
505.12000

SQL change word command

How to change the location of the letters 5 and 6 in sql. For example:
word:weather new word:weatehr
You can try to use SUBSTRING with LEN function to make it.
CREATE TABLE T(
col varchar(40)
);
INSERT INTO T VALUES ('weather')
Query 1:
SELECT
col 'word' ,CONCAT(SUBSTRING(col,1,4),SUBSTRING(col,6,1),SUBSTRING(col,5,1),SUBSTRING(col,7,LEN(col) - 5)) 'new word'
FROM T
Results:
| word | new word |
|---------|----------|
| weather | weatehr |
declare #s varchar(32) = 'weather';
set #s = stuff(#s, 5, 2, reverse(substring(#s, 5, 2)));
Since you're just reversing adjacent characters it's a little easier than swapping arbitrary characters.

Split a column in two based based on variable lenght field

Hi: I have a table made with rows like this:
ID_CATEGORIA CATEGORIA_DRG
------------ ---------------------------------------------------------------
1 001-002-003-543 Craniotomia
2 004-531-532 Interventi midollo spinale
3 005-533-534 Interventi vasi extracranici
4 006 Decompressione tunnel carpale
I'd like to get something like this:
ID CATEGORIA DESCRIZIONE
------------ ------------------ --------------------------------------
1 001-002-003-543 Craniotomia
2 004-531-532 Interventi midollo spinale
3 005-533-534 Interventi vasi extracranici
4 006 Decompressione tunnel carpale
I don't need to alter the table, a 'formatted' query can be enough.
I Think SUBSTRING() is the right function for me, but I don't know how to mesaure the lenght of the first (numbers, dash-separated) field.
In Python I'll find that size with len("005-533-534 Interventi vasi extracranici".split(' ')[0])', but I don't have idea about how to write it in SQL
Something like this should do -
SELECT ID_CATEGORIA AS ID ,SUBSTRING(CATEGORIA_DRG,1,CHARINDEX(' ',CATEGORIA_DRG)) as CATEGORIA,SUBSTRING(CATEGORIA_DRG,CHARINDEX(' ',CATEGORIA_DRG),LEN(CATEGORIA_DRG)) AS DESCRIZIONE
FROM TABLENAME
Try this:
select id_categoria ID,
substring(categoria_drg, 1, idx) CATEGORIA,
substring(categoria_drg, idx + 1, 1000) DESCRIZIONE
from (
select id_categoria, categoria_drg, charindex(' ', categoria_drg) idx from my_table
) a
It uses charindex to detect when the code is finished, because it is followed by first space in the string, which the function finds :)

add leading zeros to a varchar column

Select len(productid),productid,*
FROM dbo.produts
where Place = 'KA'
and len(productid) <> 10
order by len(productid)
this query filters the data that needs to be updated
-- i need to update the data in 'productid' that is not in the correct format
--(the data should be 10 characters, in 4-2-4 format with leading 0s where they are needed) (productid column is a varchar (256) column)
basically i need to add leading zeros to a varchar column that has a where condition
|productid| |Correct productid value| |
---------------------------------------
|234-55-43||000234-55-43|
|76-7-89||0000076-7-89|
what are the possible solutions for updating these records?
This is very simple, actually:
SELECT productid,
RIGHT('000000000'+productid,10) CorrectProductid
FROM dbo.YourTable
;
If you wanted the corrected format to be in the 4-2-4 format you mentioned:
Using parsename() to parse out the pieces of the string, and right() to add the extra '0's.
select
col
, Corrected = right('0000'+parsename(replace(col,'-','.'),3),4)
+ '-' + right('00'+parsename(replace(col,'-','.'),2),2)
+ '-' + right('0000'+parsename(replace(col,'-','.'),1),4)
from t
where col not like '____-__-____'
rextester demo: http://rextester.com/OXM28014
returns:
+-----------+--------------+
| col | Corrected |
+-----------+--------------+
| 234-55-43 | 0234-55-0043 |
| 76-7-89 | 0076-07-0089 |
+-----------+--------------+
As an update:
update t
set col = right('0000'+parsename(replace(col,'-','.'),3),4)
+ '-' + right('00'+parsename(replace(col,'-','.'),2),2)
+ '-' + right('0000'+parsename(replace(col,'-','.'),1),4)
where col not like '____-__-____'