select only integer from right before certain character - sql-server

I want a simple solution to select only numbers from right of a VARCHAR column
before a certain character.
For example, in the strings below, I only want to select numbers before slash character. The numbers vary, it can be 1 digit or more.
'ST/11/SCI/1' 'ST/11/SCI/22' 'ST/11/BIO/854' 'ST/11/BIO/5421'

You can use REVERSE with CHARINDEX so as to locate the position of the last '/' character. Then use RIGHT to extract the number:
DECLARE #str VARCHAR(100) = 'ST/11/BIO/854'
SELECT RIGHT(#str, CHARINDEX('/', REVERSE(#str)) - 1)
Edit:
To get second number starting from the end you can use:
DECLARE #str VARCHAR(100) = 'ST/11/BIO/1288/544'
SELECT SUBSTRING(#str, q2.x + 2, q2.x - q1.x - 1)
FROM (SELECT #str AS v) AS t
CROSS APPLY (SELECT CHARINDEX('/', REVERSE(#str))) AS q1(x)
CROSS APPLY (SELECT CHARINDEX('/', REVERSE(#str), q1.x + 1)) AS q2(x)
CROSS APPLY (SELECT LEN(#str)) AS s(l)

Use SUBSTRING, CHARINDEX, REVERSE
REVERSE : It will REVERSE your original string value
CHARINDEX : It will find index/location of any character from string value
SUBSTRING : It will split your string value
DECLARE #myString as VARCHAR(50)='ST/11/SCI/22'
SELECT
REVERSE
(
SUBSTRING
(
REVERSE(#myString),
0,
CHARINDEX('/',REVERSE(#myString))
)
)

I poste this as another answer, because the approach is completely different to the one of my other answer:
Starting with SQL Server 2012 (thx #NEER!) there is PARSENAME, which is a very straight approach to split a dot-delimited string up to 4 parts:
DECLARE #stringTable TABLE(string VARCHAR(100));
INSERT INTO #stringTable VALUES
('ST/11/SCI/1'),('ST/11/SCI/22'),('ST/11/BIO/854'),('ST/11/BIO/5421');
SELECT PARSENAME(REPLACE(s.string,'/','.'),1)
FROM #stringTable AS s
The result
1
22
854
5421

If you need all data you can split this easily and type-safe:
DECLARE #stringTable TABLE(string VARCHAR(100));
INSERT INTO #stringTable VALUES
('ST/11/SCI/1'),('ST/11/SCI/22'),('ST/11/BIO/854'),('ST/11/BIO/5421');
SELECT s.string
,x.value('/x[1]','nvarchar(10)') AS Part1
,x.value('/x[2]','int') AS Part2
,x.value('/x[3]','nvarchar(10)') AS Part3
,x.value('/x[4]','int') AS Part4
FROM #stringTable AS s
CROSS APPLY(SELECT CAST('<x>' + REPLACE(s.string,'/','</x><x>')+'</x>' AS XML)) AS A(x)
The result
string Part1 Part2 Part3 Part4
ST/11/SCI/1 ST 11 SCI 1
ST/11/SCI/22 ST 11 SCI 22
ST/11/BIO/854 ST 11 BIO 854
ST/11/BIO/5421 ST 11 BIO 5421

You can use a combination of reverse and charindex :
select reverse(left(reverse(...), charindex('/', reverse(...)) -1))
Documentation of reverse : https://msdn.microsoft.com/fr-fr/library/ms180040.aspx
Documentation of charindex : https://msdn.microsoft.com/fr-fr/library/ms186323.aspx
Test: select reverse(left(reverse('ST/11/SCI/2'), charindex('/', reverse('ST/11/SCI/2')) -1))
Output: 2
Note: We didnt know your version of SQL-Server, check the documentation of reverse/charindex to know wich version of SQL Server is supported !

Related

Regex in SQL Server Replace function

I have a variable with random text, let's say
DECLARE #sNumberFormat NVARCHAR(200) = 'rand{text.here,{999}also-Random9He8re'
I want to replace each 9 in {999} by [0-9]. So in this example I would like to get
'rand{text.here,[0-9][0-9][0-9]also-Random9He8re'
Problem is I never know how many 9 will be placed in brackets, so there can be {99} {9999} ..and go on. I also need to validate if there is any invalid character (not 9) then nothing should be replaced.
I have tried some combinations of REPLACE and PATINDEX functions, but I could not achieve that.
Sans robust regex support, SQL Server's native functions do not give much help here. One approach, a bit hackish, would be to separate the input string into three components:
rand{text.here,
{999}
also-Random9He8re
Next, replace the 9 in the middle target substring with #, or some other character which you don't expect to appear anywhere else in your input string:
rand{text.here,
{###}
also-Random9He8re
Finally, replace the # in the middle substring with [0-9] and then concatenate together to get the final result:
DECLARE #val NVARCHAR(200) = 'rand{text.here,{999}also-Random9He8re'
SELECT REPLACE(
SUBSTRING(#val, 1, CHARINDEX('{9', #val) - 1) +
REPLACE(SUBSTRING(#val,
CHARINDEX('{9', #val) + 1,
CHARINDEX('9}', #val) - CHARINDEX('{9', #val)), '9', '#') +
SUBSTRING(#val, CHARINDEX('9}', #val) + 2, LEN(#val) - CHARINDEX('9}', #val)),
'#', '[0-9]');
So the lazy dev in me suggests this:
SELECT Replace(
Replace(
Replace(
Replace(#input, '{9999}', '[0-9][0-9][0-9][0-9]')
, '{999}', '[0-9][0-9][0-9]')
, '{99}', '[0-9][0-9]')
, '{9}', '[0-9]') AS result
;
You can keep extending as long as you like to perform your (one off?) replacements.
Quick. Simple. Extensible. Hacky.
Sometimes lazy is good enough.
This could be done with CTE series. It works with an arbitrary number of "9" values in square brackets.
Declare #str varchar(max) = 'rand{text.here,{999}also-Random9He8re';
With A As
(Select 1 As Pos
Union All
Select Pos+1 As Pos From A Where Pos < LEN(#str)
),
B As (
Select STRING_AGG(Case When Chr Like '[{9}]' Then Chr Else ' ' End, '') As Chr
From A Cross Apply (Select SUBSTRING(#str,A.Pos,1 )) As T(chr)
),
C As (
Select [value] As pattern,
REPLACE(REPLACE(REPLACE([value], '9', '[0-9]'),'{',''),'}','') As replacement,
ROW_NUMBER() Over (ORDER BY (SELECT NULL)) As Num,
COUNT(*) OVER (ORDER BY (SELECT NULL)) As Cnt
From B Cross Apply STRING_SPLIT(Chr,' ')
Where [value] Like '{%}' And [value] Like '%9%'
),
D As (
Select #str As Result, 1 As Num
Union All
select REPLACE(Result, C.pattern, C.replacement) As Res , D.Num+1 As Num
From D Inner Join C On (D.Num=C.Num)
Where D.Num<=C.Cnt)
Select Top 1 Result
From D
Order by Num Desc
A - Getting a list of character positions in text
B - Getting text with spaces instead of characters other than
'9','{','}'
C- Getting patterns and corresponding replacement values
D - Getting the result using REPLACEMENT function

SQL for Splitting a string by hyphen, and then generating all the suffixes for each chunk that is 3 or more chars in length?

I am working with a Prefix Search engine, and I am trying to generate suffix keywords for my part numbers.
**Example String: 123456-7890-A-BCDEF-GHIJ-KL
I am looking to split this string into chunks, like this:
123456
7890
A
BCDEF
GHIJ
KL
Then I need to generate the suffixes of each chunk that is more that 3 chars in length, into one comma delimited list.
--For chunk 123456, I would get the suffixes 23456, 3456, 456, 56
--For chunk 7890, I would get the suffixes 890, 90
--For chunk A, it would be ignored as it is less than 3 chars in Length
--For chunk BCDEF, I would get the suffixes CDEF, DEF, EF
--For chunk GHIJ, I would get the suffixes HIJ, IJ
--For chunk KL, it would be ignored as it is less than 3 chars in Length
My string could have any amount of chars in each chunk, they are not always formatted like the example.
So the final result for string 123456-7890-A-BCDEF-GHIJ would look like this;
23456, 3456, 456, 56, 890, 90, CDEF, DEF, EF, HIJ, IJ
My string could have any amount of chars in each chunk, they are not always formatted like the example.
Some other example strings;
123-4567890-ABC-DEFGHIJ-K-L
--Result: 23, 567890, 67890, 7890, 890, 90, BC, EFGHIJ, FGHIJ, GHIJ, HIJ, IJ
123456-7-890AB-CDEFG-H-IJKL
--Result: 23456, 3456, 456, 56, 90AB, 0AB, AB, DEFG, EFG, FG, JKL, KL
I acknowledge this is not quite what you are looking for, but it is close. Perhaps this will give you or someone else an idea to get exactly what you want. This assumes SQL Server 2017 or higher.
So I am using STRING_SPLIT() to divide the string into one row for each chunk numbering those rows using ROW_NUMBER(). There is a problem with this in that STRING_SPLIT() does not guarantee order.
I then use a CTE to basically come up with index values to step through the each chunk from 2 to chunk length - 1 putting those strings back into a comma-separated list for each chunk using STRING_AGG().
I insert those results to a temp table so that I can select them in order by row number and assemble the suffixes from each chunk into the final comma-separated list.
DECLARE #MyString VARCHAR(50);
SET #MyString = '123456-7890-A-BCDEF-GHIJ';
WITH cte
AS (SELECT
2 AS n -- anchor member
, value
, ROW_NUMBER() OVER (ORDER BY value) AS [rn]
FROM STRING_SPLIT(#MyString, '-')
WHERE LEN(value) >= 3
UNION ALL
SELECT
n + 1
, cte.value -- recursive member
, cte.rn
FROM cte
WHERE n < (LEN(value) - 1) -- terminator
)
SELECT STRING_AGG(SUBSTRING(value, n, LEN(value) - n + 1), ', ') as [Chunk]
INTO #Temp
FROM cte
GROUP BY rn
ORDER BY rn;
SELECT STRING_AGG(Chunk, ', ')
FROM #Temp
Here is the dbfiddle.
There is probably a more elegant way to do this and likely better string manipulators than t-sql, but this seems to work: (requires DB to be compatibility mode = SQL 2016 or above to use STRING_SPLIT)
DECLARE #STRING VARCHAR (100)
DECLARE #DIVIDEON CHAR (1)
DECLARE #FULLSTRING VARCHAR (100)
DECLARE #SUBSTR VARCHAR (100)
DECLARE #WRKSTRING VARCHAR (100)
DECLARE #LEN TINYINT
SELECT #STRING = '123456-7-890AB-CDEFG-H-IJKL'
SELECT #DIVIDEON = '-'
SELECT #FULLSTRING =''
IF OBJECT_ID('tempdb..#mytable') IS NOT NULL
DROP TABLE #mytable
select RIGHT(value,LEN(value)-1) as MyString
into #mytable
from STRING_SPLIT (#STRING, #DIVIDEON) -- only SQL 2016 and above
where len(value)>2 -- ignore subsets that do not have 3 or more chars
while exists (select MyString from #mytable)
begin
select #WRKSTRING = (select top 1 MyString from #mytable)
select #LEN = len(#WRKSTRING)
select #SUBSTR=#WRKSTRING
while #LEN>2
begin
select #SUBSTR=#SUBSTR+', '+RIGHT(#WRKSTRING,#LEN-1)
select #LEN=#LEN-1
end
delete from #mytable where MyString = #WRKSTRING
--select #SUBSTR as Fullstr
select #FULLSTRING=#FULLSTRING+#SUBSTR+','
end
select LEFT(#FULLSTRING,LEN(#FULLSTRING)-1)
drop table #mytable
--not performant...maybe good enough(?)
declare #t table
(
id int identity primary key clustered,
thecol varchar(40)
);
insert into #t(thecol)
values('1-2-3-4-5-6'), ('abcd') /*??*/;
insert into #t(thecol)
select top (10000) newid()
from master.dbo.spt_values as a
cross join master.dbo.spt_values as b;
select *,
thelist= replace(
cast('<!--'+replace(thecol, '-', '--><!--')+'-->' as xml).query('
let $seq := (2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) (: note: max 22 chars per string-part:)
for $a in comment()
let $str := string($a), $maxlen := string-length($str)-1
for $i in $seq[. <= $maxlen]
return concat(substring($str, $i, 100), "," )
').value('.', 'varchar(max)')+'_', ',_', '')
from #t;

SQL String: Counting Words inside a String

I searched through many of the questions here but all I found with decent answer is for different language like Javascript etc.
I have a simple task in SQL that I can't seem to find a simple way to do.
I just need to count the number of "words" inside a SQL string (a sentence). You can see why "words" is in quotes in my examples. The "words" are delimited by white space.
Sample sentences:
1. I am not your father.
2. Where are your brother,sister,mother?
3. Where are your brother, sister and mother?
4. Who are you?
Desired answer:
1. 5
2. 4
3. 7
4. 3
As you can see, I need to count the "words" disregarding the symbols (I have to treat them as part of the word). So in sample no. 2:
(1)Where (2)are (3)your (4)brother,sister,mother? = 4
I can handle the multiple whitespaces by doing a replace like this:
REPLACE(string, ' ', ' ') -> 2 whitespaces to 1
REPLACE(string, ' ', ' ') -> 3 whitespaces to 1 and so on..
What SQL function can I use to do this? I use SQL Server 2012 but needs a function that works in SQL Server 2008 as well.
Here is one way to do it:
Create and populate sample table (Please save is this step in your future questions)
DECLARE #T AS TABLE
(
id int identity(1,1),
string varchar(100)
)
INSERT INTO #T VALUES
('I am not your father.'),
('Where are your brother,sister,mother?'),
('Where are your brother, sister and mother?'),
('Who are you?')
Use a cte to replace multiple spaces to a single space (Thanks to Gordon Linoff's answer here)
;WITH CTE AS
(
SELECT Id,
REPLACE(REPLACE(REPLACE(string, ' ', '><' -- Note that there are 2 spaces here
), '<>', ''
), '><', ' '
) as string
FROM #T
)
Query the CTE - length of the string - length of the string without spaces + 1:
SELECT id, LEN(string) - LEN(REPLACE(string, ' ', '')) + 1 as CountWords
FROM CTE
Results:
id CountWords
1 5
2 4
3 7
4 3
This is a minor improvement of #ZoharPeled's answer. This can also handle 0 length values:
DECLARE #t AS TABLE(id int identity(1,1), string varchar(100))
INSERT INTO #t VALUES
('I am not your father.'),
('Where are your brother,sister,mother?'),
('Where are your brother, sister and mother?'),
('Who are you?'),
('')
;WITH CTE AS
(
SELECT
Id,
REPLACE(REPLACE(string,' ', '><'), '<>', '') string
FROM #t
)
SELECT
id,
LEN(' '+string)-LEN(REPLACE(string, '><', ' ')) CountWords
FROM CTE
To handle multiple spaces too, use the method shown here
Declare #s varchar(100)
set #s='Who are you?'
set #s=ltrim(rtrim(#s))
while charindex(' ',#s)>0
Begin
set #s=replace(#s,' ',' ')
end
select len(#s)-len(replace(#s,' ',''))+1 as word_count
https://exploresql.com/2018/07/31/how-to-count-number-of-words-in-a-sentence/
I found this query more useful than the first. it omit extra characters and numbers and symbols, so it would count just words within a passage...
drop table if exists #t
create table #t (id int identity(1,1), c1 varchar(2000))
insert into #t (c1)
values
('Alireza Sattarzadeh Farkoush '),
('yes it is the   best .'),
('abc def ghja a the . asw'),
('?>< 123 ...!  z a b'),
('Wallex is   the greatest exchange in the .. world a after binance ...!')
select c1 , Count(*)
from (
select id, c1, value  
from #t t
cross apply (
select rtrim(ltrim(value)) as value from string_split(c1,' ')) a
where len(value) > 1 and value like '%[a-Z]%'
) Final
group by c1

Keep only desired characters and separate with semicolon in T-SQL

The problem:
I have text data imported into the db with a lot of unwanted characters. I need to keep only 4 capital letter strings within the imported text string. Example:
1447;#MIBD (This is a nice name);#2056;#LKRE (Very nice name indeed)
this could be in one column in one row of my table. What I need to extract from the string is:
MIBD and LKRE
And the result should preferably be the desired strings separated with semicolons.
It should be applied to the whole column and I cannot know how many of these 4 upper case letter strings might appear in one row.
Went through all sorts of function like PATINDEX etc. but really do not know how to approach it. thanks for any help!
try this, it assumes that the four char code is always preceded by ;# . As PATINDEX is case insensitive I have added additional check to verify that all the four character are capital.
DECLARE #MyTable Table( ID INT, MyString VARCHAR(8000))
INSERT INTO #MyTable
VALUES
(1, '1447;#MIBD (This is a nice name);#2056;#LKRE (Very nice name indeed)')
,(2, ';#DBCC (This is a nice name);#2056;#LLC (Very nice name indeed) ;#ABCD')
,(3, ';#AaaA;#OPQR;1234 (and) ;#WXYZ')
,(4, ';#abc this empty string without any code')
;WITH CTE AS
(
SELECT ID
,SUBSTRING(MyString, PATINDEX('%;#[A-Z][A-Z][A-Z][A-Z]%',MyString)+2, 4) AS NewString
,STUFF(MyString, 1, PATINDEX('%;#[A-Z][A-Z][A-Z][A-Z]%',MyString)+6, '') AS MyString
FROM #MyTable m
WHERE PATINDEX('%;#[A-Z][A-Z][A-Z][A-Z]%',MyString) > 0
UNION ALL
SELECT ID
,SUBSTRING(MyString, PATINDEX('%;#[A-Z][A-Z][A-Z][A-Z]%',MyString)+2, 4) AS NewString
,STUFF(MyString, 1, PATINDEX('%;#[A-Z][A-Z][A-Z][A-Z]%',MyString)+6, '') AS MyString
FROM CTE c
WHERE PATINDEX('%;#[A-Z][A-Z][A-Z][A-Z]%',MyString) > 0
)
SELECT c.ID,
STUFF(( SELECT '; ' + NewString
FROM CTE c1
WHERE c1.ID = c.ID
AND ASCII(SUBSTRING(NewString, 1, 1)) BETWEEN ASCII('A') AND ASCII('Z') -- first char
AND ASCII(SUBSTRING(NewString, 2, 1)) BETWEEN ASCII('A') AND ASCII('Z') -- second char
AND ASCII(SUBSTRING(NewString, 3, 1)) BETWEEN ASCII('A') AND ASCII('Z') -- third char
AND ASCII(SUBSTRING(NewString, 4, 1)) BETWEEN ASCII('A') AND ASCII('Z') -- fourth char
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)') -- use the value clause to hanlde xml character issue like, &,",>,<
,1,1,'') AS CodeList
FROM CTE c
GROUP BY ID
OPTION (MAXRECURSION 0);
I came to something like this so far:
ALTER FUNCTION CleanData
(
-- Parameters here
#Text AS VARCHAR(4000)
)
RETURNS VARCHAR(4000)
AS
BEGIN
WHILE PATINDEX('%[0-9#;()]%', #Text) > 0
BEGIN
SET #Text = STUFF(#Text, PATINDEX('%[0-9#;()]%', #Text), 1, '')
END
RETURN #Text
END
But what I get is the Initials and the characters in parantheses as the PATINDEX cannot differ between the upper and lower case. Maybe it might be helpful for somebody else

Concatenate the result of an ordered String_Split in a variable

In a SqlServer database I use, the database name is something like StackExchange.Audio.Meta, or StackExchange.Audio or StackOverflow . By sheer luck this is also the url for a website. I only need split it on the dots and reverse it: meta.audio.stackexchange. Adding http:// and .com and I'm done. Obviously Stackoverflow doesn't need any reversing.
Using the SqlServer 2016 string_split function I can easy split and reorder its result:
select value
from string_split(db_name(),'.')
order by row_number() over( order by (select 1)) desc
This gives me
| Value |
-----------------
| Meta |
| Audio |
| StackExchange |
As I need to have the url in a variable I hoped to concatenate it using this answer so my attempt looks like this:
declare #revname nvarchar(150)
select #revname = coalesce(#revname +'.','') + value
from string_split(db_name(),'.')
order by row_number() over( order by (select 1)) desc
However this only returns me the last value, StackExchange. I already noticed the warnings on that answer that this trick only works for certain execution plans as explained here.
The problem seems to be caused by the order by clause. Without that I get all values, but then in the wrong order. I tried to a add ltrimand rtrim function as suggested in the Microsoft article as well as a subquery but so far without luck.
Is there a way I can nudge the Sql Server 2016 Query Engine to concatenate the ordered result from that string_split in a variable?
I do know I can use for XML or even a plain cursor to get the result I need but I don't want to give up this elegant solution yet.
As I'm running this on the Stack Exchange Data Explorer I can't use functions, as we lack the permission to create those. I can do Stored procedures but I hoped I could evade those.
I prepared a SEDE Query to experiment with. The database names to expect are either without dots, aka StackOverflow, with 1 dot: StackOverflow.Meta or 2 dots, `StackExchange.Audio.Meta, the full list of databases is here
I think you are over-complicating things. You could use PARSENAME:
SELECT 'http://' + PARSENAME(db_name(),1) +
ISNULL('.' + PARSENAME(db_name(),2),'') + ISNULL('.'+PARSENAME(db_name(),3),'')
+ '.com'
This is exactly why I have the Presentation Sequence (PS) in my split function. People often scoff at using a UDF for such items, but it is generally a one-time hit to parse something for later consumption.
Select * from [dbo].[udf-Str-Parse]('meta.audio.stackexchange','.')
Returns
Key_PS Key_Value
1 meta
2 audio
3 stackexchange
The UDF
CREATE FUNCTION [dbo].[udf-Str-Parse] (#String varchar(max),#delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse]('meta.audio.stackexchange','.')
-- Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
-- Select * from [dbo].[udf-Str-Parse]('id26,id46|id658,id967','|')
Returns #ReturnTable Table (Key_PS int IDENTITY(1,1) NOT NULL , Key_Value varchar(max))
As
Begin
Declare #intPos int,#SubStr varchar(max)
Set #IntPos = CharIndex(#delimeter, #String)
Set #String = Replace(#String,#delimeter+#delimeter,#delimeter)
While #IntPos > 0
Begin
Set #SubStr = Substring(#String, 0, #IntPos)
Insert into #ReturnTable (Key_Value) values (#SubStr)
Set #String = Replace(#String, #SubStr + #delimeter, '')
Set #IntPos = CharIndex(#delimeter, #String)
End
Insert into #ReturnTable (Key_Value) values (#String)
Return
End
Probably less elegant solution but it takes only a few lines and works with any number of dots.
;with cte as (--build xml
select 1 num, cast('<str><s>'+replace(db_name(),'.','</s><s>')+'</s></str>' as xml) str
)
,x as (--make table from xml
select row_number() over(order by num) rn, --add numbers to sort later
t.v.value('.[1]','varchar(50)') s
from cte cross apply cte.str.nodes('str/s') t(v)
)
--combine into string
select STUFF((SELECT '.' + s AS [text()]
FROM x
order by rn desc --in reverse order
FOR XML PATH('')
), 1, 1, '' ) name
Is there a way I can nudge the Sql Server 2016 Query Engine to concatenate the ordered result from that string_split in a variable?
You can just use CONCAT:
DECLARE #URL NVARCHAR(MAX)
SELECT #URL = CONCAT(value, '.', #URL) FROM STRING_SPLIT(DB_NAME(), '.')
SET #URL = CONCAT('http://', LOWER(#URL), 'com');
The reversal is accomplished by the order of parameters to CONCAT. Here's an example.
It changes StackExchange.Garage.Meta to http://meta.garage.stackexchange.com.
This can be used to split and reverse strings in general, but note that it does leave a trailing delimiter. I'm sure you could add some logic or a COALESCE in there to make that not happen.
Also note that vNext will be adding STRING_AGG.
To answer the 'X' of this XY problem, and to address the HTTPS switch (especially for Meta sites) and some other site name changes, I've written the following SEDE query which outputs all site names in the format used on the network site list.
SELECT name,
LOWER('https://' +
IIF(PATINDEX('%.Mathoverflow%', name) > 0,
IIF(PATINDEX('%.Meta', name) > 0, 'meta.mathoverflow.net', 'mathoverflow.net'),
IIF(PATINDEX('%.Ubuntu%', name) > 0,
IIF(PATINDEX('%.Meta', name) > 0, 'meta.askubuntu.com', 'askubuntu.com'),
IIF(PATINDEX('StackExchange.%', name) > 0,
CASE SUBSTRING(name, 15, 200)
WHEN 'Audio' THEN 'video'
WHEN 'Audio.Meta' THEN 'video.meta'
WHEN 'Beer' THEN 'alcohol'
WHEN 'Beer.Meta' THEN 'alcohol.meta'
WHEN 'CogSci' THEN 'psychology'
WHEN 'CogSci.Meta' THEN 'psychology.meta'
WHEN 'Garage' THEN 'mechanics'
WHEN 'Garage.Meta' THEN 'mechanics.meta'
WHEN 'Health' THEN 'medicalsciences'
WHEN 'Health.Meta' THEN 'medicalsciences.meta'
WHEN 'Moderators' THEN 'communitybuilding'
WHEN 'Moderators.Meta' THEN 'communitybuilding.meta'
WHEN 'Photography' THEN 'photo'
WHEN 'Photography.Meta' THEN 'photo.meta'
WHEN 'Programmers' THEN 'softwareengineering'
WHEN 'Programmers.Meta' THEN 'softwareengineering.meta'
WHEN 'Vegetarian' THEN 'vegetarianism'
WHEN 'Vegetarian.Meta' THEN 'vegetarianism.meta'
WHEN 'Writers' THEN 'writing'
WHEN 'Writers.Meta' THEN 'writing.meta'
ELSE SUBSTRING(name, 15, 200)
END + '.stackexchange.com',
IIF(PATINDEX('StackOverflow.%', name) > 0,
CASE SUBSTRING(name, 15, 200)
WHEN 'Br' THEN 'pt'
WHEN 'Br.Meta' THEN 'pt.meta'
ELSE SUBSTRING(name, 15, 200)
END + '.stackoverflow.com',
IIF(PATINDEX('%.Meta', name) > 0,
'meta.' + SUBSTRING(name, 0, PATINDEX('%.Meta', name)) + '.com',
name + '.com'
)
)
)
)
) + '/'
)
FROM sys.databases WHERE database_id > 5

Resources