Select string till first or second space in string - mysql

I have table column that contains in each row data like this:
| Simbols |
|--------------------------------------|
|H412 Text text |
|H413 Text text text text |
|EUH 001 Text text text text text text |
|EUH 006 text text |
|EUH 201/201A Text text. Text text |
And I need from that data get data like this:
|Simbols |
|------------|
|H412 |
|H413 |
|EUH 001 |
|EUH 006 |
|EUH 201/201A|
I tried with SUBSTRING and CHARINDEX but it till the end don't work... It takes only first space or something like that...
QUERY:
SELECT
CASE
WHEN SUBSTRING(Simbols, 1, CHARINDEX(' ', Simbols)) = ''
THEN Simbols + ' '
ELSE SUBSTRING(Simbols, 1, CHARINDEX(' ', Simbols))
END 'Simbols'
FROM dbo.table
RESULT:
| Simbols |
|------------|
|H412 |
|H413 |
|EUH |
|EUH |
|EUH |
How can I make this work, and where is the problem?
Maybe there is different way to get these Simbols?
P.S. "Text text text" is a example, there comes a explanations of "Simbols"

The CharIndex() function has an optional 3rd parameter - start_location - that will be key here.
SELECT your_column
, CharIndex(' ', your_column) As first_space
, CharIndex(' ', your_column, CharIndex(' ', your_column) + 1) As second_space
, SubString(your_column, 1, CharIndex(' ', your_column, CharIndex(' ', your_column) + 1)) As first_two_words
FROM your_table
Unfortunately when the CharIndex() function can't find the specified string (in this case a single space ' ') it will return 0 (zero).
This means that if there isn't a first or second space the result of first_two_words in my above example will return an empty string as SubString(your_column, 1, 0) = ''.
To get around this you need to be a little clever.
Essentially, if second_space = 0 then we need to return the full string. We have a few options for this:
SELECT your_column
, CharIndex(' ', your_column) As first_space
, CharIndex(' ', your_column, CharIndex(' ', your_column) + 1) As second_space
, SubString(your_column, 1, CharIndex(' ', your_column, CharIndex(' ', your_column) + 1)) As first_two_words
, SubString(your_column, 1, Coalesce(NullIf(CharIndex(' ', your_column, CharIndex(' ', your_column) + 1), 0), Len(your_column))) As first_two_words_option1
, CASE WHEN CharIndex(' ', your_column, CharIndex(' ', your_column) + 1) = 0 THEN your_column ELSE SubString(your_column, 1, CharIndex(' ', your_column, CharIndex(' ', your_column) + 1)) END As first_two_words_option2
FROM (
SELECT 'one' As your_column
UNION ALL SELECT 'one two'
UNION ALL SELECT 'one two three'
UNION ALL SELECT 'one two three four'
) As x

Try this: It works
SELECT CASE WHEN charindex(' ', Simbols, charindex(' ', Simbols) + 1) = 0
THEN Simbols
ELSE LEFT(Simbols, charindex(' ', Simbols, charindex(' ', Simbols) + 1))
END
FROM dbo.table
Here is screenshot what I tried.
Here is new EDIT
SELECT REPLACE(Simbols, 'text', '') FROM dbo.table
Here is screen shot

Try something like this:
select TRIM(REPLACE(lower(type),"text" ,"")) as T, type from supportContacts
Sql Fiddle: http://sqlfiddle.com/#!2/d5cf8/4
for more info :http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_replace

Related

Pivoting and getting #1111 - Invalid use of group function for this query

I'm try to Pivoting and getting #1111 - Invalid use of group function for this query. I really need help here.
SELECT pack.ActionName, up.Name
SUM(IF(SUBSTRING_INDEX(SUBSTRING_INDEX(SchoolYear, ' ', 1), ' ', -1) = 'X', COUNT(tph.UniqueActionPackageId)*pack.TotalPrice, 0)) AS Total_Revenue_X,
AVERAGE(IF(SUBSTRING_INDEX(SUBSTRING_INDEX(SchoolYear, ' ', 1), ' ', -1) = 'X', Total_Revenue_X/COUNT(tph.UniqueActionPackageId),0)) AS Rataan_Kelas_X,
SUM(IF(SUBSTRING_INDEX(SUBSTRING_INDEX(SchoolYear, ' ', 1), ' ', -1) = 'XI', COUNT(tph.UniqueActionPackageId)*pack.TotalPrice, 0)) AS Total_Revenue_XI,
AVERAGE(IF(SUBSTRING_INDEX(SUBSTRING_INDEX(SchoolYear, ' ', 1), ' ', -1) = 'XI', Total_Revenue_XI/COUNT(tph.UniqueActionPackageId),0)) AS Rataan_Kelas_XI,
SUM(IF(SUBSTRING_INDEX(SUBSTRING_INDEX(SchoolYear, ' ', 1), ' ', -1) = 'XII', COUNT(tph.UniqueActionPackageId)*pack.TotalPrice, 0)) AS Total_Revenue_XII,
AVERAGE(IF(SUBSTRING_INDEX(SUBSTRING_INDEX(SchoolYear, ' ', 1), ' ', -1) = 'XII', Total_Revenue_XII/COUNT(tph.UniqueActionPackageId),0)) AS Rataan_Kelas_XII
FROM packages AS pack
JOIN transaction_package_history AS tph ON pack.ActionPackagesId = tph.UniqueActionPackageId
JOIN user_profile AS up ON up.UniqueId = tph.UserId
GROUP BY pack.ActionName;
Can you guys help me
I suspect you are trying to write something like this:
SELECT p.ActionName, up.Name
SUM(CASE WHEN SchoolYear LIKE '%X %' THEN p.TotalPrice END) as Total_Revenue_X,
AVG(CASE WHEN SchoolYear LIKE '%X %' THEN p.TotalPrice END) as Rataan_Kelas_X,
SUM(CASE WHEN SchoolYear LIKE '%XI %' THEN p.TotalPrice END) as Total_Revenue_XI,
AVG(CASE WHEN SchoolYear LIKE '%XI %' THEN p.TotalPrice END) as Rataan_Kelas_XI,
SUM(CASE WHEN SchoolYear LIKE '%XII %' THEN p.TotalPrice END) as Total_Revenue_XI,
AVG(CASE WHEN SchoolYear LIKE '%XII %' THEN p.TotalPrice END) as Rataan_Kelas_XI,
FROM packages p JOIN
transaction_package_history tph
ON p.ActionPackagesId = tph.UniqueActionPackageId JOIN
user_profile up
ON up.UniqueId = tph.UserId
GROUP BY p.ActionName;

CASE WHEN with multiple THEN ELSE

Right now i get for reporting purposes the following data in 3 different columns:
//Number
'CASE WHEN should_be.sh = "50"
THEN
REPLACE(SUBSTRING_INDEX(account.code,".",1)," ","")
ELSE
"500."
END',
// Account
'CASE WHEN should_be.sh = "50"
THEN
REPLACE(
SUBSTRING(SUBSTRING_INDEX(account.code,".",2),
INSTR(account.code, ".") + 1)
," ","")
ELSE
"92145000000"
END',
// Costsnumber
'CASE WHEN should_be.sh = "50"
THEN
CASE WHEN LENGTH(account.code) < 15
THEN
REPLACE(
SUBSTRING_INDEX(account.code,".",-1)
," ","")
ELSE
""
END
ELSE
""
END',
If every condition meets ELSE, then the 3 columns look like that:
+--------+-------------+------------+
| number | account | costnumber |
+--------+-------------+------------+
| 500 | 92145000000 | |
+--------+-------------+------------+
How to combine the 3 columns, so I will have one column like that (for example in the ELSE case:
+-------------------------+
| combined |
+-------------------------+
| 500-92145000000-(empty) |
+-------------------------+
Just use concat_ws():
CONCAT_WS('-',
(CASE WHEN should_be.sh = '50'
THEN REPLACE(SUBSTRING_INDEX(account.code, '.', 1), ' ', '')
ELSE '500.'
END),
(CASE WHEN should_be.sh = '50'
THEN REPLACE(SUBSTRING(SUBSTRING_INDEX(account.code, '.',2),
INSTR(account.code, '.') + 1), ' ', '')
ELSE '92145000000'
END),
(CASE WHEN should_be.sh = '50' AND LENGTH(account.code) < 15
THEN REPLACE(SUBSTRING_INDEX(account.code, '.', -1), ' ', '')
ELSE ''
END)
)
If you want "(empty)" to really appear for the third element, then replace the final ELSE '' with ELSE '(empty)'.

Add ellipsis with substring_index MySQL

Is it possible to add ellipsis after the MySQL substring_index function?
So if I have the following code:
SET #string = "abc, def, ghi, jkl, mno";
SELECT SUBSTRING_INDEX(#string, ', ', 3);
The result is: abc, def, ghi
So is it possible to add ... at the back ONLY when it is cut?
I wish to retrieve this:
SELECT SUBSTRING_INDEX(#string, ', ', 3);
---> RESULT: abc, def, ghi...
SELECT SUBSTRING_INDEX(#string, ', ', 5);
---> RESULT: abc, def, ghi, jkl, mno
You need some conditional logic:
select (case when #string = substring_index(#string, ', ', 3)
then substring_index(#string, ', ', 3)
else concat(substring_index(#string, ', ', 3), '...')
end)

SQL dynamically pivot and group results

I have a table set up like below:
CLIENTNAME MONTHANDYEAR RESOURCE COST
abc JAN2011 res1 1000
abc FEB2011 res1 2000
def JAN2011 res2 1500
def MAR2011 res1 2000
ghi MAR2011 res3 2500
I need an output like below. Months are to be generated dynamically in 3-month intervals. In this case, is there a way to pivot by MONTHANDYEAR as well as group by clientname?
RESOURCE CLIENTNAME JAN2011 FEB2011 MAR2011
res1 abc 1000 1000
res1 def 2000
res2 def 1500
res3 ghi 2500
This is what the PIVOT operator is for:
SELECT
Resource, ClientName,
[JAN2011], [FEB2011], [MAR2011]
FROM
(
SELECT
*
FROM tblname
) AS SourceTable
PIVOT
(
SUM(COST)
FOR MONTHANDYEAR IN ([JAN2011], [FEB2011], [MAR2011])
) AS PivotTable;
Since your months are selected dynamically using #startDate as a base month, you can use the following dynamic query:
DECLARE #startDate datetime
SET #startDate = '2011-01-01'
DECLARE #sql varchar(MAX)
SET #sql = 'SELECT
Resource, ClientName, [' +
REPLACE(SUBSTRING(CONVERT(varchar, #startDate, 13), 4, 8), ' ', '') + '], [' +
REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 1, #startDate), 13), 4, 8), ' ', '') + '], [' +
REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 2, #startDate), 13), 4, 8), ' ', '') + ']
FROM
(
SELECT
*
FROM tblName
) AS SourceTable
PIVOT
(
SUM(COST)
FOR MONTHANDYEAR IN (' +
QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, #startDate, 13), 4, 8), ' ', '')) + ', ' +
QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 1, #startDate), 13), 4, 8), ' ', '')) + ', ' +
QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 2, #startDate), 13), 4, 8), ' ', '')) + ')
) AS PivotTable'
execute(#sql)
working sqlfiddle here
This data transformation can be done with the PIVOT function.
If you know the values, then you can hard-code the monthandyear dates:
select resource,
clientname,
isnull(jan2011, '') Jan2011,
isnull(feb2011, '') Feb2011,
isnull(mar2011, '') Mar2011
from
(
select clientname, monthandyear, resource, cost
from yourtable
) src
pivot
(
sum(cost)
for monthandyear in (Jan2011, Feb2011, Mar2011)
) piv;
See SQL Fiddle with Demo.
But if the dates are unknown, then you will need to use dynamic SQL:
DECLARE #cols AS NVARCHAR(MAX),
#colNames AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(monthandyear)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select #colNames = STUFF((SELECT distinct ', isnull(' + QUOTENAME(monthandyear)+', 0) as '+QUOTENAME(monthandyear)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT resource, clientname,' + #colNames + ' from
(
select clientname, monthandyear, resource, cost
from yourtable
) x
pivot
(
sum(cost)
for monthandyear in (' + #cols + ')
) p '
execute(#query)
See SQL Fiddle with Demo.
The result of both is:
| RESOURCE | CLIENTNAME | JAN2011 | FEB2011 | MAR2011 |
-------------------------------------------------------
| res1 | abc | 1000 | 2000 | 0 |
| res1 | def | 0 | 0 | 2000 |
| res2 | def | 1500 | 0 | 0 |
| res3 | ghi | 0 | 0 | 2500 |
SELECT Resource, Clientname
, SUM(CASE WHEN MonthAndYear = 'JAN2011' THEN COST ELSE 0 END) AS JAN2011
, SUM(CASE WHEN MonthAndYear = 'FEB2011' THEN COST ELSE 0 END) AS FEB2011
, SUM(CASE WHEN MonthAndYear = 'MAR2011' THEN COST ELSE 0 END) AS MAR2011
FROM yourtable
GROUP BY Resource, Clientname
You can also remove the ELSE 0 to return a NULL value for resource/clientname combinations without data

T-SQL substring - separating first and last name

I have a column which has FirstName and LastName together. I'm writing a report to separate the FirstName And LastName. How do I get the FirstName and LastName separated in T-SQL?
Assuming the FirstName is all of the characters up to the first space:
SELECT
SUBSTRING(username, 1, CHARINDEX(' ', username) - 1) AS FirstName,
SUBSTRING(username, CHARINDEX(' ', username) + 1, LEN(username)) AS LastName
FROM
whereever
The easiest way I can find to do it is:
SELECT
SUBSTRING(FullName, 1, CHARINDEX(' ', FullName) - 1) AS FirstName,
REVERSE(SUBSTRING(REVERSE(FullName), 1, CHARINDEX(' ', REVERSE(FullName)) - 1)) AS LastName
FROM
[PERSON_TABLE]
This should work:
Select
LTRIM(RTRIM(SUBSTRING(FullName, 0, CHARINDEX(' ', FullName)))) As FirstName
, LTRIM(RTRIM(SUBSTRING(FullName, CHARINDEX(' ', FullName)+1, 8000)))As LastName
FROM TABLE
Edit: Adopted Aaron's and Jonny's hint with the fixed length of 8000 to avoid unnecessary calculations.
validate last name is blank
SELECT
person.fullName,
(CASE WHEN 0 = CHARINDEX(' ', person.fullName)
then person.fullName
ELSE SUBSTRING(person.fullName, 1, CHARINDEX(' ', person.fullName)) end) as first_name,
(CASE WHEN 0 = CHARINDEX(' ', person.fullName)
THEN ''
ELSE SUBSTRING(person.fullName,CHARINDEX(' ', person.fullName), LEN(person.fullName) )end) last_name
FROM person
Here is a more elaborated solution with a SQL function:
GetFirstname
CREATE FUNCTION [dbo].[ufn_GetFirstName]
(
#FullName varchar(500)
)
RETURNS varchar(500)
AS
BEGIN
-- Declare the return variable here
DECLARE #RetName varchar(500)
SET #FullName = replace( replace( replace( replace( #FullName, '.', '' ), 'Mrs', '' ), 'Ms', '' ), 'Mr', '' )
SELECT
#RetName =
CASE WHEN charindex( ' ', ltrim( rtrim( #FullName ) ) ) > 0 THEN left( ltrim( rtrim( #FullName ) ), charindex( ' ', ltrim( rtrim( #FullName ) ) ) - 1 ) ELSE '' END
RETURN #RetName
END
GetLastName
CREATE FUNCTION [dbo].[ufn_GetLastName]
(
#FullName varchar(500)
)
RETURNS varchar(500)
AS
BEGIN
DECLARE #RetName varchar(500)
IF(right(ltrim(rtrim(#FullName)), 2) <> ' I')
BEGIN
set #RetName = left(
CASE WHEN
charindex( ' ', reverse( ltrim( rtrim(
replace( replace( replace( replace( replace( replace( #FullName, ' Jr', '' ), ' III', '' ), ' II', '' ), ' Jr.', '' ), ' Sr', ''), 'Sr.', '')
) ) ) ) > 0
THEN
right( ltrim( rtrim(
replace( replace( replace( replace( replace( replace( #FullName, ' Jr', '' ), ' III', '' ), ' II', '' ), ' Jr.', '' ), ' Sr', ''), 'Sr.', '')
) ) , charindex( ' ', reverse( ltrim( rtrim(
replace( replace( replace( replace( replace( replace( #FullName, ' Jr', '' ), ' III', '' ), ' II', '' ), ' Jr.', '' ), ' Sr', ''), 'Sr.', '')
) ) ) ) - 1 )
ELSE '' END
, 25 )
END
ELSE
BEGIN
SET #RetName = left(
CASE WHEN
charindex( ' ', reverse( ltrim( rtrim(
replace( replace( replace( replace( replace( replace( replace( #FullName, ' Jr', '' ), ' III', '' ), ' II', '' ), ' I', '' ), ' Jr.', '' ), ' Sr', ''), 'Sr.', '')
) ) ) ) > 0
THEN
right( ltrim( rtrim(
replace( replace( replace( replace( replace( replace( replace( #FullName, ' Jr', '' ), ' III', '' ), ' II', '' ), ' I', '' ), ' Jr.', '' ), ' Sr', ''), 'Sr.', '')
) ) , charindex( ' ', reverse( ltrim( rtrim(
replace( replace( replace( replace( replace( replace( replace( #FullName, ' Jr', '' ), ' III', '' ), ' II', '' ), ' I', '' ), ' Jr.', '' ), ' Sr', ''), 'Sr.', '')
) ) ) ) - 1 )
ELSE '' END
, 25 )
END
RETURN #RetName
END
USE:
SELECT dbo.ufn_GetFirstName(Fullname) as FirstName, dbo.ufn_GetLastName(Fullname) as LastName FROM #Names
You could do this if firstname and surname are separated by space:
SELECT SUBSTRING(FirstAndSurnameCol, 0, CHARINDEX(' ', FirstAndSurnameCol)) Firstname,
SUBSTRING(FirstAndSurnameCol, CHARINDEX(' ', FirstAndSurnameCol)+1, LEN(FirstAndSurnameCol)) Surname FROM ...
This will take care of names like "Firstname Z. Lastname" and "First Z Last"
SELECT
CASE
WHEN CHARINDEX(' ',name) = 0 THEN name
WHEN CHARINDEX(' ',name) = PATINDEX('% _[., ]%',name) THEN RTRIM(SUBSTRING(name, 1, CHARINDEX(' ',name) + 2))
ELSE SUBSTRING(name,1, CHARINDEX(' ',name))
END [firstname]
,CASE
WHEN CHARINDEX(' ',name) = 0 THEN ''
WHEN CHARINDEX(' ',name) = PATINDEX('% _[., ]%',name) THEN LTRIM(SUBSTRING(name, CHARINDEX(' ',name) + 3,1000))
ELSE SUBSTRING(name,CHARINDEX(' ',name)+1,1000)
END [lastname]
FROM [myTable]
I think below query will be helpful to split FirstName and LastName from FullName even if there is only FirstName.
For example: 'Philip John' can be split into Philip and John.
But if there is only Philip, because of the charIndex of Space is 0, it will only give you ''.
Try the below one.
declare #FullName varchar(100)='Philp John'
Select
LTRIM(RTRIM(SUBSTRING(#FullName, 0, CHARINDEX(' ', #FullName+' ')))) As FirstName
, LTRIM(RTRIM(SUBSTRING(#FullName, CHARINDEX(' ', #FullName+' ')+1, 8000)))As LastName
Hope this will help you. :)
You may have problems if the Fullname doesn't contain a space.
Assuming the whole of FullName goes to Surname if there is no space and FirstName becomes an empty string, then you can use this:
SELECT
RTRIM(LEFT(FullName, CHARINDEX(' ', FullName))) AS FirstName,
SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, 8000) AS LastName
FROM
MyNameTable;
The code below works with Last, First M name strings. Substitute "Name" with your name string column name. Since you have a period as a final character when there is a middle initial, you would replace the 2's with 3's in each of the lines (2, 6, and 8)- and change "RIGHT(Name, 1)" to "RIGHT(Name, 2)" in line 8.
SELECT SUBSTRING(Name, 1, CHARINDEX(',', Name) - 1) LastName ,
CASE WHEN LEFT(RIGHT(Name, 2), 1) <> ' '
THEN LTRIM(SUBSTRING(Name, CHARINDEX(',', Name) + 1, 99))
ELSE LEFT(LTRIM(SUBSTRING(Name, CHARINDEX(',', Name) + 1, 99)),
LEN(LTRIM(SUBSTRING(Name, CHARINDEX(',', Name) + 1, 99)))
- 2)
END FirstName ,
CASE WHEN LEFT(RIGHT(Name, 2), 1) = ' ' THEN RIGHT(Name, 1)
ELSE NULL
END MiddleName
For the last name as in US standards (i.e., last word in the [Full Name] column) and considering first name to include a possible middle initial, middle name, etc.:
SELECT DISTINCT
[Full Name]
,REVERSE([Full Name]) -- to visualize what the formula is doing
,CHARINDEX(' ', REVERSE([Full Name])) -- finds the last space in the string
,[Last Name] = REVERSE(RTRIM(LTRIM(LEFT(REVERSE([Full Name]), CHARINDEX(' ', REVERSE([Full Name]))))))
,[First Name] = RTRIM(LTRIM(LEFT([Full Name], LEN([Full Name]) - CHARINDEX(' ', REVERSE([Full Name])))))
FROM ...
Note that this assumes [Full Name] has no spaces before or after the actual string. Otherwise, use RTRIM and LTRIM to remove these.
Let's suppose your table has Name column and it contains data like -
Random Person
FIRST LAST
Alpha Beta
The query will be like this
SELECT
LEFT(NAME,CHARINDEX(' ',NAME)) AS "First Name",
LTRIM(RTRIM(SUBSTRING(NAME,CHARINDEX(' ',NAME),100))) AS "Last Name"
FROM YOUR_TABLE