SELECT
right(name,7),
substring(params, charindex('|-|', params)+3,LEN(params)) as 'List Name',
convert(varchar,dateadd(hh,-8,created_date), 101) as Date,
convert(char, dateadd(hh,-8,created_date), 108) as Time
FROM
[meldb].[dbo].[mr_message]
WHERE
name in ('CL_LIST_STARTED', 'CL_LIST_STOPPED')
AND dateadd(hh,-8,created_date) > '7/1/2014'
ORDER BY
created_date ASC
List name will return something like:
firstname.lastname-|LISTNAME|-|PARENTLISTNAME
I'm trying to isolate LISTNAME and PARENTLISTNAME into separate columns, but since they can vary in char size I can't just specify right or left
Btw I didn't create this table I'm just stuck using it
Any ideas?
Did you try it yet?
Ok... happy friday :)
declare #str varchar(100);
set #str = 'jim.smith|-|firstItem|-|secondItem';
--- for your query, change #str to the column name, obviously ---
select
substring(
#str
, charindex('|-|', #str) + 3
, ( ( charindex('|-|', #str, charindex('|-|', #str) + 3) ) - ( charindex('|-|', #str) + 3) )
)
,substring(
#str
, charindex('|-|', #str, charindex('|-|', #str) + 3) + 3
, len(#str) -- guaranteed to be past the end, to catch all
)
Do you want to split params into three columns? Please check below query.
SELECT
SUBSTRING(params, 1, CHARINDEX('-', params)-1) AS FullName,
SUBSTRING(STUFF(params, CHARINDEX('|-|', params), LEN(params), ''), CHARINDEX('-', params) + 2, LEN(params)) AS 'List Name',
SUBSTRING(params, CHARINDEX('|-|', params) + 3, LEN(params)) AS 'Parent List Name',
CONVERT(VARCHAR,DATEADD(hh,-8,created_date), 101) AS DATE,
CONVERT(CHAR, DATEADD(hh,-8,created_date), 108) AS TIME
FROM
[meldb].[dbo].[mr_message]
WHERE
name IN ('CL_LIST_STARTED', 'CL_LIST_STOPPED')
AND DATEADD(hh,-8,created_date) > '7/1/2014'
ORDER BY
created_date ASC
Here is the format I came up with using PAT index and the separators you mentioned:
SELECT name,
substring(name, 0, charindex('.', name)) as 'FirstName',
substring(name, charindex('.', name) + 1, patindex('%|-|%', name) - patindex('%-|%', name) -2) as 'LastName',
substring(name,patindex('%-|%', name)+2, patindex('%|-|%', name) - patindex('%-|%', name)-2) as 'ListName',
substring(name, patindex('%|-|%', name)+3, len(name) - patindex('%|-|%', name)) as 'ParentListName'
from FancyNames
Link to SQL Fiddle: http://sqlfiddle.com/#!6/03c2c/38
Related
I was asked to query only first letters of name and surname from a column in SQL Server. And the rest should be "*" instead of letters
For example: Waldemar Fisar, should be queried like. W******* F****
Updated question:
I am getting this:
John Snow after query becomes J S
Lora White after query becomes L W
But need to get:
-John Snow should become J*** S***
-Jonathan Conan J******* C****
Lastly, both names and surnames are in the same column
SELECT
Personal info, SUBSTRING([Primary Contact], 1, 1) + ' ' +
SUBSTRING([Primary Contact], CHARINDEX(' ', [Primary Contact]) + 1, 1) AS CI
FROM
xx
You can write a function for that task like the example below:
create function hide_name(#text nvarchar(max), #ch nchar(1), #n int)
returns nvarchar(max)
as
begin
return LEFT(#text, #n) + REPLICATE(#ch, LEN(#text) - #n)
end
go
SELECT
dbo.hide_name(yourNameColumn, '*', 1) + ' ' + dbo.hide_name(yourFamilyNameColumn, '*', 1)
FROM yourTableName
Not recommended, but someone might need
declare #Person table (
name nvarchar(max),
surname nvarchar(max)
);
insert into #Person values ('John', 'Snow'), ('Lora', 'White');
select CONCAT(
IIF(len(name) > 0, concat(LEFT(name, 1), REPLICATE('*', len(name) - 1)), ''),
IIF(len(name) > 0 and len(surname) > 0, ' ', ''),
IIF(len(surname) > 0, concat(LEFT(surname, 1), REPLICATE('*', len(name) - 1)), '')
) as HiddenName
from #Person
SELECT
Personal info, SUBSTRING([Primary Contact], 1, 1) + ' ' +
SUBSTRING([Primary Contact], CHARINDEX(' ', [Primary Contact]) + 1, 1) AS CI
, SUBSTRING([Primary Contact], 1, 1) + replicate('*',CHARINDEX(' ', [Primary Contact])-2)
+ ' ' +
SUBSTRING([Primary Contact], CHARINDEX(' ', [Primary Contact]) + 1, 1)
+ replicate('*',len([Primary Contact]) - CHARINDEX(' ', [Primary Contact])-1) AS CI_Star
FROM
xx
A pure positional solution
DROP TABLE IF EXISTS #names
GO
CREATE TABLE #names(thename NVARCHAR(50))
INSERT INTO #names(thename)
VALUES
('Alison Arnold'),
('Dorothy Jones'),
('Christopher Mackay'),
('Jason H Paterson'),
('Thomas Johnson'),
('Dave')
SELECT subnames.thename,STRING_AGG(subnames.maskedsubname,' ')
FROM
(
SELECT
n.TheName,
SubNames.SubName,
LEFT(SubNames.SubName,1)+REPLICATE('*',(LEN(SubNames.SubName)-1))AS MaskedSubName
FROM #names n
CROSS APPLY(SELECT Value AS SubName FROM STRING_SPLIT(n.TheName,' ')) SubNames
)subnames
GROUP BY SubNames.SubName
Basically what I am trying to do is that I want to get the middle word, using the second occurrence of the same character (on this case, dash "-").
This is the sample input:
declare #word nvarchar(max)
set #word = 'Technical Materials - Conversion - Team Dashboard'
There are three parts on this sentence, and they are divided by '-' dash line.
The first part is 'Technical Materials' which I am able to get using:
SELECT LTRIM(RTRIM(SUBSTRING(#word, 0, CHARINDEX('-', #word, 0))))
The last set was 'Team Dashboard' which I am able to get using:
SELECT CASE WHEN LEN(#word) - LEN(REPLACE(#word, '-', '')) = 1
THEN NULL
ELSE
RIGHT(#word,CHARINDEX('-', REVERSE(#word))-1)
END
The problem was, I am having a hard time getting the middle words which is 'Conversion' in this example.
If the format is fixed, you can use PARSENAME to achieve your expectation:
DECLARE #Word AS NVARCHAR(MAX) = 'Technical Materials - Conversion - Team Dashboard'
SELECT PARSENAME(REPLACE(#Word, '-', '.'), 2)
if you want to trim the extra spaces, then:
SELECT LTRIM(RTRIM(PARSENAME(REPLACE(#Word, '-', '.'), 2)))
Try this query:
SELECT
SUBSTRING(#word,
CHARINDEX('-', #word) + 2,
CHARINDEX('-', #word, CHARINDEX('-', #word) + 1) -
CHARINDEX('-', #word) - 3)
FROM yourTable
The general strategy here is to use SUBSTRING(), which requires the starting and ending positions of the middle string in question. We can use CHARINDEX to find both the first and second dash in the string. From this, we can compute the positions of the middle substring we want.
Demo here:
Rextester
This will find the text between the first 2 occurrences of '-'
DECLARE #word nvarchar(max)
SET #word = 'Technical Materials - Conversion - Team Dashboard'
SELECT SUBSTRING(x, 0, charindex('-', x))
FROM (values(stuff(#word, 1, charindex('-', #word), ''))) x(x)
This will find the middle element. In case of an even number of elements it will pick the first of the 2 middle elements
DECLARE #word nvarchar(max)
SET #word = 'Technical Materials - Conversion - Team Dashboard'
;WITH CTE(txt, rn, cnt) as
(
SELECT
t.c.value('.', 'VARCHAR(2000)'),
row_number() over (order by (select 1)), count(*) over()
FROM (
SELECT x = CAST('<t>' +
REPLACE(#word, ' - ', '</t><t>') + '</t>' AS XML)
) a
CROSS APPLY x.nodes('/t') t(c)
)
SELECT txt
FROM CTE
WHERE (cnt+1) / 2 = rn
I have a name field in Students table which is a comma separated string in format "LastName, FirstName, Middle Name".While doing a select statement in SQL query I need to break this up into separate fields.How can I achieve this in SQL?.Some times Middle intial won't be available.
SUBSTRING(Name,CHARINDEX(',',Name,1)+2,LEN(Name)) AS FirstName,
SUBSTRING(Name,1,CHARINDEX(',',Name,1)-1) AS LastName,
Above code works fine when there is no Middle name.
This should give you what you need:
declare #tmp table (fullname varchar(100));
insert #tmp values('James, Billy, L'), ('John, Snow');
select
fullname
, [Last Name]
, case
when charindex(',', Remainder, 0) > 0
then ltrim(substring(Remainder, 0, charindex(',', Remainder, 0)))
else ltrim(Remainder)
end [First Name]
, case
when charindex(',', Remainder, 0) = 0
then NULL
else ltrim(substring(Remainder, charindex(',', Remainder, 0) + 1, len(Remainder)))
end [Middle Name]
from
(select
fullname
, substring(fullname, 0, charindex(',', fullname, 0)) [Last Name]
, substring(fullname, charindex(',', fullname, 0) + 1, len(fullname)) [Remainder]
from #tmp) result;
First just find the occurrences of comma(,) in the string. Then use CASE expression to get the number of comma. If there is 2 comma then we can assume that middle name is also there. If 1 then only first name and last name. Then use the combinations of LEFT, RIGHT, SUBSTRING, CHARINDEX string functions.
Query
select t.name,
left(
t.name,
charindex(',', t.name, 1) - 1
) last_name,
case t.comma_num
when 2
then substring(
t.name,
charindex(',', t.name, 1) + 1,
len(name) -
(charindex(',', t.name, 1) + 1) - charindex(',', reverse(t.name), 1) + 1
)
when 1
then right(
t.name,
charindex(',', reverse(t.name), 1) - 1
)
else null end as first_name,
case t.comma_num
when 2
then right(
t.name, charindex(',', reverse(t.name), 1) - 1
)
else null end as middle_name
from (
select name,
len(name) - len(replace(name, ',', '')) comma_num
from [your_table_name]
)t;
Find demo here
Use CTE and SUBSTRING AND CHARINDEX funntions
DECLARE #Name VARCHAR(100) = 'James, Billy, L'
--DECLARE #Name VARCHAR(100) = 'James, '', L'
;WITH _CTE ( SplitedNames ,RemainStr) AS
(
SELECT SUBSTRING(#Name,0,CHARINDEX(',',#Name)),
SUBSTRING(#Name,CHARINDEX(',',#Name)+1,LEN(#Name))
UNION ALL
SELECT CASE WHEN CHARINDEX(',',RemainStr) = 0 THEN RemainStr ELSE
SUBSTRING(RemainStr,0,CHARINDEX(',',RemainStr)) END,
CASE WHEN CHARINDEX(',',RemainStr) = 0 THEN '' ELSE
SUBSTRING(RemainStr,CHARINDEX(',',RemainStr)+1,LEN(RemainStr))
END
FROM _CTE
WHERE RemainStr <> ''
)
SELECT SplitedNames FROM _CTE
How do I get only the middle part of the data in my table? I tried the following code, but this only removes the right part... my output should only be middle part.
For instance when I select the data 1-021514-1 the output should be 021514 without the left and right dashes
select LEFT(ticketid, CHARINDEX('-', ticketid + '-') + 4)
from Table
My Data is:
|TicketID |
------------
|1-021514-1 |
|10-021514-1|
|2-021514-1 |
|4-021414-1 |
Please try:
SELECT
LEFT(st, CHARINDEX('-', st)-1) TicketID
from
(
SELECT
SUBSTRING(TicketID, CHARINDEX('-',TicketID)+1, 10000) st
FROM Table
)x
Try this
with t as (select TicketID as val)
select t.*,
LEFT(val, charindex('-', val) - 1),
SUBSTRING(val, charindex('-', val)+1, len(val) - CHARINDEX('-', reverse(val)) - charindex('-', val)),
REVERSE(LEFT(reverse(val), charindex('-', reverse(val)) - 1))
from t;
(Or)
Use below Function
CREATE FUNCTION dbo.SplitStrings_CTE(#List nvarchar(max), #Delimiter nvarchar(1))
RETURNS #returns TABLE(val nvarchar(max), [level] int, PRIMARY KEY CLUSTERED([level]))
AS
BEGIN
;WITH cte AS
(
SELECT SUBSTRING(#List, 0, CHARINDEX(#Delimiter, #List)) AS val,
CAST(STUFF (#List + #Delimiter, 1, CHARINDEX(#Delimiter, #List), '') AS nvarchar(max)) AS stval,
1 AS [level]
UNION ALL
SELECT SUBSTRING(stval, 0, CHARINDEX(#Delimiter, stval)),
CAST(STUFF (stval, 1, CHARINDEX(#Delimiter, stval), '') AS nvarchar(max)),
[level] + 1
FROM cte
WHERE stval != ''
)
INSERT #returns
SELECT REPLACE(val, ' ', '') AS val, [level]
FROM cte
RETURN
END
hi Ron try this,
declare #string varchar(25)='1-021514-1'
declare #val varchar(25)
SELECT #val= SUBSTRING(#string, CHARINDEX('-', #string)+1, ((CHARINDEX('-',#string,(charindex('-',#string)+1))-CHARINDEX('-', #string))-1))
select #val
Try this:
select right(left(ticketid, charindex('-', ticketid, charindex('-', ticketid, 0) + 1) - 1), len(left(ticketid, charindex('-', ticketid, charindex('-', ticketid, 0) + 1) - 1)) - charindex('-', left(ticketid, charindex('-', ticketid, charindex('-', ticketid, 0) + 1) - 1), 0)) from Table
Try this
SELECT STUFF(
STUFF(TicketID,1,CHARINDEX('-',TicketID,1),'')
,CHARINDEX('-',STUFF(TicketID,1,CHARINDEX('-',TicketID,1),''),1)
,LEN(TicketID)
,'')
from Table1
I need to return everything in a string before the space:
select Substring('stack overflow', 1, CharIndex( ' ', 'stack overflow' ) - 1)
this will yield stack
however if we don't have a space in the data, i would like to return the entire string:
select Substring('stackoverflow', 1, CharIndex( ' ', 'stackoverflow' ) - 1)
i would like that to return stackoverflow
what is the correct way to handle this scenario?
;WITH T(C) AS
(
SELECT 'stack overflow' UNION ALL
SELECT 'stackoverflow'
)
SELECT LEFT(C, CharIndex( ' ', C + ' ' ) - 1)
FROM T
Borrowing #MartinSmith's definition:
;WITH T(C) AS
(
SELECT 'stack overflow'
UNION ALL
SELECT 'stackoverflow'
)
SELECT SUBSTRING(C, 1, COALESCE(NULLIF(CHARINDEX(' ', C)-1, -1), 255))
FROM T;
That said, I prefer Martin's. Both avoid checking the length or performing CASE etc., but mine assumes you know the max length of the string (here I assumed 255).
I'm late as per usual; here on SQL Fiddle
CREATE TABLE The_Table
(
TestString varchar(50)
);
INSERT INTO The_Table
(TestString)
VALUES
('stack overflow'),
('stackoverflow');
select
[myResult] = case
when CharIndex( ' ', TestString)> 0 then Substring(TestString, 1, CharIndex( ' ', TestString ) - 1)
when CharIndex( ' ', TestString)= 0 then TestString
else TestString
end
from The_Table
;With T(C) AS
(
Select 'Stack'
Union All
Select 'Stack OverFlow'
)
Select
Case When CharIndex(' ', C) > 0
Then SUBSTRING(C, 0, CharIndex(' ', C))
Else
C
End
From T
Declare #str varchar(100)='stack overflow'
SELECT CASE WHEN CHARINDEX(' ',#str,1) > 0 then LEFT(#str,CHARINDEX(' ',#str,1)) else #str END