Add ellipsis with substring_index MySQL - 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)

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;

Update statement in nested query

I have an update query.But it showing sql error
Query
Update ms_student set student_first_name=y.student_first_name,student_middle_name=y.student_middle_name,student_last_name=y.student_last_name FROM
(SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(student_name, ' ', 1), ' ', -1) as student_first_name,
SUBSTRING_INDEX(SUBSTRING_INDEX(student_name, ' ', 2), ' ', -1) as student_middle_name,
SUBSTRING_INDEX(SUBSTRING_INDEX(student_name, ' ', 3), ' ', -1) as student_last_name
FROM ms_student) y
My inner query working perfectly.But In update having issue
Why you need subquery you can do with simple update command
update ms_student
set
student_first_name= SUBSTRING_INDEX(SUBSTRING_INDEX(student_name, ' ', 1), ' ', -1),
student_middle_name = SUBSTRING_INDEX(SUBSTRING_INDEX(student_name, ' ', 2), ' ', -1),
student_last_name = SUBSTRING_INDEX(SUBSTRING_INDEX(student_name, ' ', 3), ' ', -1) ;
You came have multiple table in update clause
Update ms_student x,(SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(student_name, ' ', 1), ' ', -1) as student_first_name,
SUBSTRING_INDEX(SUBSTRING_INDEX(student_name, ' ', 2), ' ', -1) as student_middle_name,
SUBSTRING_INDEX(SUBSTRING_INDEX(student_name, ' ', 3), ' ', -1) as student_last_name
FROM ms_student) y
set x.student_first_name=y.student_first_name,x.student_middle_name=y.student_middle_name,x.student_last_name=y.student_last_name;

Select string till first or second space in string

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

SQL: Using ISNULL with dynamic pivot

I want to make all the NULL values produced by the pivot to become 0s. I have placed ISNULL in every place imaginable, but does not seem to have any effect. Are pivots compatible with ISNULL? Code below:
DECLARE #startDate datetime
SET #startDate = '2013-01-01'
DECLARE #sql varchar(MAX)
SET #sql = 'SELECT
CLIENTNAME, PROJECTNAME, RESOURCE, [' +
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), ' ', '') + '], [' +
REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 3, #startDate), 13), 4, 8), ' ', '') + '], [' +
REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 4, #startDate), 13), 4, 8), ' ', '') + '], [' +
REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 5, #startDate), 13), 4, 8), ' ', '') + ']
FROM
(
SELECT
CLIENTNAME, PROJECTNAME, RESOURCE, FORECASTTOTAL
FROM viewprojscheduling_group
) AS SourceTable
PIVOT
(
SUM(FORECASTTOTAL)
FOR SCHEDULEDDATE 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), ' ', '')) + ', ' +
QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 3, #startDate), 13), 4, 8), ' ', '')) + ', ' +
QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 4, #startDate), 13), 4, 8), ' ', '')) + ', ' +
QUOTENAME(REPLACE(SUBSTRING(CONVERT(varchar, DATEADD(MONTH, 5, #startDate), 13), 4, 8), ' ', '')) + ')
) AS PivotTable'
execute(#sql)
I would set your query up slightly different because while it is dynamic in that the column names are changing, you have still hard-coded the number of columns.
First, I would use a recursive CTE to generate the list of months/years that you want to create.
DECLARE #startDate datetime
SET #startDate = '2013-01-01'
;with dates as
(
select #startdate datelist, 1 sp
union all
select dateadd(month, 1, datelist), sp+1
from dates
where sp+1 <= 5 -- change this number 5 to the number of months you need
)
select sp,
REPLACE(SUBSTRING(CONVERT(varchar(11), datelist, 13), 4, 8), ' ', '') MONTHANDYEAR
from dates
See SQL Fiddle with Demo. This is going to create your list of the 5 months with the year automatically. Then you are not hard-coding the 5 columns. Your current query is not as flexible as it could be. What will happen if you then want 12 months, you are going to have to change your code.
Once you generate the list of dates, I would insert it into a temp table so you can use it to get the columns.
The code to get the list of columns is:
select #cols = STUFF((SELECT ',' + QUOTENAME(monthandyear)
from #datesTemp
group by monthandyear, sp
order by sp
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select #colNames = STUFF((SELECT ', isnull(' + QUOTENAME(monthandyear)+', 0) as '+QUOTENAME(monthandyear)
from #datesTemp
group by monthandyear, sp
order by sp
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
See SQL Fiddle with Demo. You will see that there are two versions. The first one #cols gets the list of columns that will be used in the pivot. The second #colNames will be used in the final SELECT list to replace the null values with the zeros.
Then you put it all together and the code will be: (Note: I am using a version of my answer from your previous question)
DECLARE #cols AS NVARCHAR(MAX),
#colNames AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#startDate datetime
SET #startDate = '2013-01-01'
;with dates as
(
select #startdate datelist, 1 sp
union all
select dateadd(month, 1, datelist), sp+1
from dates
where sp+1 <= 5 -- change this number 5 to the number of months you need
)
select sp,
REPLACE(SUBSTRING(CONVERT(varchar(11), datelist, 13), 4, 8), ' ', '') MONTHANDYEAR
into #datesTemp
from dates
select #cols = STUFF((SELECT ',' + QUOTENAME(monthandyear)
from #datesTemp
group by monthandyear, sp
order by sp
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select #colNames = STUFF((SELECT ', isnull(' + QUOTENAME(monthandyear)+', 0) as '+QUOTENAME(monthandyear)
from #datesTemp
group by monthandyear, sp
order by sp
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT resource, clientname,' + #colNames + '
from
(
select [CLIENTNAME], [RESOURCE], [FORECASTTOTAL],
REPLACE(SUBSTRING(CONVERT(varchar(11), SCHEDULEDDATE, 13), 4, 8), '' '', '''') monthandyear
from viewprojscheduling_group
) x
pivot
(
sum(FORECASTTOTAL)
for monthandyear in (' + #cols + ')
) p '
execute(#query)
See SQL Fiddle with Demo. This query will give you the result:
| RESOURCE | CLIENTNAME | JAN2013 | FEB2013 | MAR2013 | APR2013 | MAY2013 |
---------------------------------------------------------------------------
| res1 | abc | 1000 | 2000 | 0 | 0 | 0 |
| res1 | def | 0 | 0 | 2000 | 0 | 0 |
| res2 | def | 1500 | 0 | 0 | 0 | 0 |
| res3 | ghi | 0 | 0 | 2500 | 0 | 0 |

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