Convert Alphanumeric value to a unique numeric value in SQL - sql

I have a table column with values like below
V5H 3K3
V6L 4L4
V4E 5L2
V5H 3K3
I need to get a unique number against each of them so it would look something like
V5H 3K3 1111
V6L 4L4 2222
V4E 5L2 3333
V5H 3K3 1111
Is there a simple function in SQL Server that can be used to do this?

Select cast(HashBytes('MD5', 'V5H 3K3') as int)
Returns
-381163718
For Example
Declare #Table table (SomeField varchar(25))
Insert into #Table values
('V5H 3K3'),
('V6L 4L4'),
('V4E 5L2'),
('V5H 3K3')
Select *,AsAnInt = abs(cast(HashBytes('MD5', SomeField) as int))
From #Table
Returns
SomeField AsAnInt
V5H 3K3 381163718
V6L 4L4 245350301
V4E 5L2 1706996605
V5H 3K3 381163718

Related

Find and replace by pattern

I have a table that has a column like the one below
url
----------------
dir=mp3\cat152AB&fileName=file-01.mp3
dir=mp3\cat2500DfDD00&fileName=file-02.mp3
dir=mp3\cat4500f0655&fileName=file-03.mp3
...
How can I delete extra strings and arrange the fields as follows in SQL Server.
url
----------------
file-01
file-02
file-03
...
you can use charindex and substring :
SELECT substring ('dir=mp3\cat152AB&fileName=file-01.mp3', CHARINDEX('fileName=', 'dir=mp3\cat152AB&fileName=file-01.mp3') +9 ,
LEN('dir=mp3\cat152AB&fileName=file-01.mp3')-CHARINDEX('fileName=', 'dir=mp3\cat152AB&fileName=file-01.mp3')
) AS MatchPosition;
CHARINDEX and SUBSTRING can help you, please check the example:
select substring (field, charindex (';fileName=', field) + len (';fileName='), len (field) - len ('.mp3') + 1 - charindex (';fileName=', field) - len (';fileName='))
from (
select 'dir=mp3\cat152AB&fileName=file-01.mp3' field union all
select 'dir=mp3\cat2500DfDD00&fileName=file-02.mp3' union all
select 'dir=mp3\cat4500f0655&fileName=file-03.mp3'
) a
The information you want always seems to be the 11th to 5th characters before the end of the string. I would suggest a simple solution:
select left(right(url, 11), 7)
Here is a db<>fiddle.
Please try the following method.
It is using tokenization via XML/XQuery.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (ID INT IDENTITY PRIMARY KEY, url VARCHAR(255));
INSERT INTO #tbl (url) VALUES
('dir=mp3\cat152AB&fileName=file-01.mp3'),
('dir=mp3\cat2500DfDD00&fileName=file-02.mp3'),
('dir=mp3\cat4500f0655&fileName=file-03.mp3');
-- DDL and sample data population, end
DECLARE #separator CHAR(1) = '=';
SELECT id, url
, LEFT(x, CHARINDEX('.', x) - 1) AS Result
FROM #tbl
CROSS APPLY (SELECT CAST('<root><r><![CDATA[' +
REPLACE(url, #separator, ']]></r><r><![CDATA[') +
']]></r></root>' AS XML)) AS t1(c)
CROSS APPLY (VALUES (c.value('(/root/r[last()]/text())[1]', 'VARCHAR(100)'))) AS t2(x);
Output
+----+------------------------------------------------+---------+
| id | url | Result |
+----+------------------------------------------------+---------+
| 1 | dir=mp3\cat152AB&fileName=file-01.mp3 | file-01 |
| 2 | dir=mp3\cat2500DfDD00&fileName=file-02.mp3 | file-02 |
| 3 | dir=mp3\cat4500f0655&fileName=file-03.mp3 | file-03 |
+----+------------------------------------------------+---------+
I know we have an accepted answer but I wanted to chime in with another simple, high-performing solution that addresses file names and file extensions with various lengths. For fun I included a parameter that allows you to include the file extension if you choose.
--==== Easily Consumable Sample Data
DECLARE #link TABLE ([url] VARCHAR(100) UNIQUE);
INSERT #link VALUES ('dir=mp3\cat152AB&fileName=file-01.mp3'),
('dir=mp3\cat2500DfDD00&fileName=file-02.mp3'),
('dir=mp3\cat4500f0655&fileName=file-03.mp3'),
('dir=mp3\cat4500f0655&fileName=file-999.mp3'),
('dir=mp3\cat4500d9997&fileName=file-0021.prodigi');
--==== Allows you to determine if you want the file extension
DECLARE #exclude BIT=1;
SELECT l.[url], TheFile = SUBSTRING(l.[url], s.Pos, s.Ln-s.Pos- ((#exclude*(fl.Ln)-1)))
FROM #link AS l
CROSS APPLY (VALUES(CHARINDEX('.',REVERSE(l.[url])))) AS fl(Ln)
CROSS APPLY (VALUES(CHARINDEX('fileName=',l.[url])+9, LEN(l.[url]))) AS s(Pos,Ln);
#exclude=1 returns:
url TheFile
----------------------------------------------------- --------------
dir=mp3\cat152AB&fileName=file-01.mp3 file-01
dir=mp3\cat2500DfDD00&fileName=file-02.mp3 file-02
dir=mp3\cat4500d9997&fileName=file-0021.prodigi file-0021
dir=mp3\cat4500f0655&fileName=file-03.mp3 file-03
dir=mp3\cat4500f0655&fileName=file-999.mp3 file-999
#exclude=0 returns:
url TheFile
----------------------------------------------------- --------------
dir=mp3\cat152AB&fileName=file-01.mp3 file-01.mp3
dir=mp3\cat2500DfDD00&fileName=file-02.mp3 file-02.mp3
dir=mp3\cat4500d9997&fileName=file-0021.prodigi file-0021.prodigi
dir=mp3\cat4500f0655&fileName=file-03.mp3 file-03.mp3
dir=mp3\cat4500f0655&fileName=file-999.mp3 file-999.mp3

how to extract a value from xml document in postgresql

How to extract the value of clientid from the following xml document in Postgres?
I want to get value 1435 from this xml:
CREATE TABLE xmltest3(xtxt xml);
INSERT INTO xmltest3 values ('<clients><client clientId="1435"/></clients>');
SELECT unnest(xpath('./client /text()', xtxt::xml))::text AS XMLDATA FROM XMLTEST3;
I tried:
SELECT unnest(xpath('./clients/text()', xtxt::xml))::text AS XMLDATA
FROM XMLTEST3;
But it is not working.
Also, how to extract the ENvalues from this?
<ENList><EN ENValue="Liquidity"/><EN ENValue="Treasury"/></ENList>
Use #clientId to get the attribute value:
with invar as (
select '<clients><client clientId="1435"/></clients>'::xml as x
)
select unnest(xpath('/clients/client/#clientId', x))
from invar;
unnest
--------
1435
(1 row)
The concept is the same for your other example:
with invar as (
select '<ENList><EN ENValue="Liquidity"/><EN ENValue="Treasury"/></ENList>'::xml as x
)
select unnest(xpath('/ENList/EN/#ENValue', x))
from invar;
unnest
-----------
Liquidity
Treasury
(2 rows)

Leading 0 on int Column problem SQL Server

I have an issue where I am trying to add a leading 0 to run an output.
SELECT
CASE
WHEN LEN(t.trans_time) = 5
THEN CONCAT(0, [trans_time])
ELSE T.[trans_time]
END AS [TransactionTime]
,RIGHT(CONCAT(0,trans_time),6) AS trans_time
,LEN(T.trans_Time)
,t.trans_time
Why does the case statement not return the leading 0 whereas using:
,RIGHT(CONCAT(0,trans_time),6) AS trans_time
Works no problem.
Case expression return only one type, whereas concat() would return different type & i am assuming trans_time has INT type.
So, you would need to do type conversations :
SELECT (CASE WHEN LEN(t.trans_time) = 5
THEN CONCAT(0, [trans_time])
ELSE CAST(T.[trans_time] AS VARCHAR(255))
END) AS [TransactionTime],
. . .
Another way to do this is to use the format function, wich is available from sql server 2012.
It not only makes the code more readable but will also perform better.
declare #t table (id int)
insert into #t values (90113), (90204), (90207), (90235), (90302), (90318), (90324)
select format(id, '000000') as TransactionTime from #t
this will return
TransactionTime
---------------
090113
090204
090207
090235
090302
090318
090324

Select row when value is in range

Given the two column below how can I select the row 110-118 if my filter is 111? 100-118 is a range thus 111 falls between 100-118
Dest_ZIP Ground
004-005 003
009 005
068-089 002
100-118 001
Below is a simple example of how to do this in SQL using a sub query to get the start and end range. This can be expanded on to better handle parsing the string value.
Declare #Temp TABLE
(
Dest_Zip varchar(7),
Ground varchar(3)
)
INSERT INTO #Temp VALUES ('004-005','003')
INSERT INTO #Temp VALUES ('068-089','002')
INSERT INTO #Temp VALUES ('100-118','001')
SELECT A.Dest_Zip, A.Ground FROM
(
select
Convert(int, SUBSTRING(Dest_Zip,1,3)) StartNum,
Convert(int, SUBSTRING(Dest_Zip,5,3)) EndNum,
*
from #Temp
) AS A
WHERE 111 >= A.StartNum AND 111 <= A.EndNum
Fix the data. Here is a simple way using computed columns (and assuming the "zips" are always 3 characters):
alter table t
add column minzip as (left(dest_zip), 3),
add column maxzip as (right(dest_zip), 3);
Then, you can run the query as:
select t.*
from t
where '111' between t.minzip and t.maxzip;
You can even create an index on computed columns, which can help performance (although not much in this case).
If you wish to make the checks in php, maybe this sample code can help you:
<?php
$my_string = "111";
$foo = "100-118"; // our range
$bar = explode('-', $foo); // Get an array .. let's call it $bar
// Print the output, see how the array looks
//print_r($bar);
//echo $bar[0].'<br />';
//echo $bar[1].'<br />';
if(($bar[0] <= $my_string ) AND ($bar[1] >= $my_string)){ echo 'true';} else { echo 'false';}
?>

Restrict specific date format Data into Table

I Have a table called Sur_Data and the data looks like:
ID SV_Date
258 13/01/2010
569 15/02/2011
695 26/05/2010
745 12/06/2010
Now I want to select the ID's from that table and insert into another table so we are using something like:
Insert into Surdate(ID)
Select ID from Sur_Data
where ISDATE(SV_Date) = 1
Since the format in SV_Date is different it is not inserting any records into Surdate table.
So I am trying to see is there a way that we could restrict the data in Sur_Data table to have only date's that are in MM/DD/YYYY format.So whenever they try to insert records of different format it should throw an error.
Can anyone help on this?
Edit: for example 2 & 3, ANSI WARNINGS must be off.
IS_DATE function is influenced by DATEFORMAT setting for current SQL Server session/connection.
Example 1:
DECLARE #d1 VARCHAR(25) = '26/05/2010'
,#d2 VARCHAR(25) = '15/02/2011';
PRINT '*****Test 1*****'
SET DATEFORMAT DMY;
SELECT ISDATE(#d1), ISDATE(#d2);
PRINT '*****Test 2*****'
SET DATEFORMAT MDY;
SELECT ISDATE(#d1), ISDATE(#d2);
Results:
*****Test 1*****
----------- -----------
1 1
(1 row(s) affected)
*****Test 2*****
----------- -----------
0 0
(1 row(s) affected)
Now, you can see how DATEFORMAT influences ISDATE function.
Instead of ISDATE function you can use CONVERT function with different date/time styles. If a [n][var]char value doesn't have the selected style then CONVERT function will return NULL. For dd/mm/yyyy values (british) can be used style 103 and for mm/dd/yyyy values (U.S.) can be used style 101.
Example 2:
SET ANSI_WARNINGS OFF;
SET ARITHABORT OFF;
DECLARE #Results TABLE
(
ID INT PRIMARY KEY
,SV_Date VARCHAR(20) NOT NULL
);
INSERT #Results
VALUES
(258, '13/01/2010')
,(569, '15/02/2011')
,(695, '26/05/2010')
,(745, '12/06/2010');
SELECT *
,ISDATE(r.SV_Date) [IS_DATETIME]
,CONVERT(DATETIME,r.SV_Date,103) [IS_DATETIME British/French style=dd/mm/yyyy]
,CONVERT(DATETIME,r.SV_Date,101) [IS_DATETIME U.S. style=mm/dd/yyyy]
,CASE
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NOT NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NULL THEN 'IS_DMY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NOT NULL THEN 'IS_MDY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NOT NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NOT NULL THEN 'IS_DMY_OR_MDY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NULL THEN 'IS_NOT_DMY_OR_MDY'
END
FROM #Results r;
Results:
ID SV_Date IS_DATETIME IS_DATETIME British/French style=dd/mm/yyyy IS_DATETIME U.S. style=mm/dd/yyyy
----------- -------------------- ----------- ------------------------------------------- --------------------------------- -----------------
258 13/01/2010 0 2010-01-13 00:00:00.000 NULL IS_DMY
569 15/02/2011 0 2011-02-15 00:00:00.000 NULL IS_DMY
695 26/05/2010 0 2010-05-26 00:00:00.000 NULL IS_DMY
745 12/06/2010 1 2010-06-12 00:00:00.000 2010-12-06 00:00:00.000 IS_DMY_OR_MDY
Now, if you want to check SV_Date values for mm/dd/yyyy format (style 101 - U.S.) then you can use a CHECK constraint like this:
Example 3:
DECLARE #Results2 TABLE
(
ID INT PRIMARY KEY
,SV_Date VARCHAR(20) NOT NULL
,CHECK( CONVERT(DATETIME,SV_Date,101) IS NOT NULL )
);
SET ANSI_WARNINGS OFF;
INSERT #Results2
VALUES (258, '13/01/2010');
INSERT #Results2
VALUES (569, '15/02/2011');
INSERT #Results2
VALUES (695, '26/05/2010');
INSERT #Results2
VALUES (745, '12/06/2010');
SELECT *
FROM #Results2;
Results:
ID SV_Date
----------- --------------------
745 12/06/2010
(1 row(s) affected)
Observations:
If you want to find current DATEFORMAT setting (current session) then you can use sys.dm_exec_sessions view:
SELECT s.date_format, s.date_first
FROM sys.dm_exec_sessions s
WHERE s.session_id = ##SPID
To strictly answer the question, you could create a function (CLR or TSQL) and apply that as a column constraint/check.
But as #joe Stefanelli correctly points out, store it as a datetime data type and let the client handle the presentation format.
Edit
http://msdn.microsoft.com/en-us/library/ms190273.aspx
ALTER TABLE
dbo.Sur_Data
WITH CHECK
ADD CONSTRAINT ck_dateFormatted CHECK (dbo.VerifyDateFormat(SV_Date) = 1) ;
Which assumes you've defined a function that returns 1 if the format matches the expectation.