I have a problem with the request below!
REQUEST:
SELECT COALESCE(date(date_field), 'Total') AS "date_field_group",
COUNT( id_field ) AS "Nombre de bookings",
CONCAT( REPLACE( REPLACE( FORMAT( SUM( price1 ) , 2 ) , ',', ' ' ) , '.', ',' ) , ' €' ) AS "Total à l'achat",
CONCAT( REPLACE( REPLACE( FORMAT( SUM( price2 ) , 2 ) , ',', ' ' ) , '.', ',' ) , ' €' ) AS "Total à la vente",
CONCAT( REPLACE( REPLACE( FORMAT( SUM( price2 ) - SUM( price1 ) , 2 ) , ',', ' ' ) , '.', ',' ) , ' €' ) AS 'Marge',
CONCAT( REPLACE( FORMAT( (SUM( price2 ) / SUM( price1 ) ) , 2 ) , '1.', '' ) , ' ', '%') AS "Markup moyen"
FROM table1 S, table2 B
WHERE status_field
IN ( "1", "5")
AND DATE( date_field ) BETWEEN "2011-08-01" AND "2011-08-31"
AND type_field = "H"
AND price1 IS NOT NULL
AND S.id_field = B.id_field
AND B.id2 = "1"
GROUP BY date_field_group WITH ROLLUP
The thing is that the request is working fine (right numbers), but in the last line I was expected to get in first row "Total" and instead of that I got a field NULL...
Is someone know what is wrong with my request ?
Thx for any help ;).
You're query is almost correct (except for using implicit SQL '89 joins, which is an SQL anti-pattern)
The problem is in the last line: GROUP BY ... WITH ROLLUP.
The rollup gets applied very late in the process, after your COALESCE(date(date_field), 'Total').
So the coalesce has already finished by the time rollup comes along you need to rewrite the query like so:
SELECT COALESCE(date_field_group, 'Total') as date_field_group
, `Nombre de bookings`
, `Total à l'achat`
, `Total à la vente`
, `Marge`
, `Markup moyen`
FROM (
SELECT date(date_field) AS "date_field_group",
COUNT( id_field ) AS "Nombre de bookings",
CONCAT( REPLACE( REPLACE( FORMAT( SUM( price1 ) , 2 ) , ',', ' ' ) , '.', ',' ) , ' €' ) AS "Total à l'achat",
CONCAT( REPLACE( REPLACE( FORMAT( SUM( price2 ) , 2 ) , ',', ' ' ) , '.', ',' ) , ' €' ) AS "Total à la vente",
CONCAT( REPLACE( REPLACE( FORMAT( SUM( price2 ) - SUM( price1 ) , 2 ) , ',', ' ' ) , '.', ',' ) , ' €' ) AS 'Marge',
CONCAT( REPLACE( FORMAT( (SUM( price2 ) / SUM( price1 ) ) , 2 ) , '1.', '' ) , ' ', '%') AS "Markup moyen"
FROM table1 S
INNER JOIN table2 B ON (S.id_field = B.id_field)
WHERE status_field IN ( "1", "5")
AND DATE( date_field ) BETWEEN "2011-08-01" AND "2011-08-31"
AND type_field = "H"
AND price1 IS NOT NULL
AND B.id2 = "1"
GROUP BY date_field_group WITH ROLLUP ) AS subquery
Related
I have a view in SQL that when I want to open it gives me the following message: #1242 - Subquery returns more than 1 line.
How can I correct this query considering my sql script?
My code is:
SELECT
`sc`.`id` AS `id`,
`sc`.`id_agente_solicitado` AS `id_agente_solicitado`,
`sc`.`id_agente_solicitante` AS `id_agente_solicitante`,
`sc`.`fecha_solicitada` AS `fecha`,
`sc`.`horario_solicitado` AS `hora`,
`sc`.`pendiente` AS `pendiente`,
'1' AS `tipo`,
'Cambios de horarios' AS `grupo`,
'1' AS `grupo_numero`,
CONCAT(`a`.`nombres`, ' ', `a`.`apellidos`) AS `agente_solicitado_nombre`,
(
SELECT
CONCAT(
`sigsiste_bd`.`agentes`.`nombres`,
' ',
`sigsiste_bd`.`agentes`.`apellidos`
)
FROM
`sigsiste_bd`.`agentes`
WHERE
(
`sigsiste_bd`.`agentes`.`id_agente` = `sc`.`id_agente_solicitante`
)
) AS `agente_solicitante_nombre`,
(
SELECT
`sigsiste_bd`.`agentes`.`imagen_perfil`
FROM
`sigsiste_bd`.`agentes`
WHERE
(
`sigsiste_bd`.`agentes`.`id_agente` = `sc`.`id_agente_solicitante`
)
) AS `imagen_perfil_solicitante`,
`a`.`imagen_perfil` AS `imagen_perfil_solicitado`,
DAYNAME(`sc`.`fecha_solicitada`) AS `nombre_dia`,
CONCAT(
CONVERT(
DATE_FORMAT(`sc`.`fecha_solicitada`, '%d') USING utf8mb4
),
' de ',
CONVERT(
MONTHNAME(`sc`.`fecha_solicitada`) USING utf8mb4
),
' de ',
CONVERT(
DATE_FORMAT(`sc`.`fecha_solicitada`, '%Y') USING utf8mb4
)
) AS `nombre_mes`,
(
SELECT
CONCAT(' ', `det`.`ingreso`)
FROM
(
`sigsiste_bd`.`planilla_horarios_det` `det`
LEFT JOIN `sigsiste_bd`.`planilla_horarios_cab` `cab`
ON
(
(
`cab`.`id_planilla_horarios_cab` = `det`.`id_planilla_horarios_cab`
)
)
)
WHERE
(
(
STR_TO_DATE(
CONCAT(
`cab`.`ano_correspondiente`,
',',
`cab`.`mes_correspondiente`,
',',
`det`.`dia`
),
'%Y,%m,%d'
) = `sc`.`fecha_solicitada`
) AND(
`sc`.`id_agente_solicitante` = `det`.`id_agente`
)
)
) AS `cambio_por`
FROM
(
`sigsiste_bd`.`solicitudes_cambio_horario` `sc`
LEFT JOIN `sigsiste_bd`.`agentes` `a`
ON
(
(
`a`.`id_agente` = `sc`.`id_agente_solicitado`
)
)
)
UNION ALL
SELECT
`sc`.`id` AS `id`,
`sc`.`id_agente_solicitado` AS `id_agente_solicitado`,
`sc`.`id_agente_solicitante` AS `id_agente_solicitante`,
`sc`.`fecha_cobertura` AS `fecha`,
`sc`.`horario_cobertura` AS `hora`,
`sc`.`pendiente` AS `pendiente`,
'2' AS `tipo`,
'Coberturas' AS `grupo`,
'2' AS `grupo_numero`,
CONCAT(`a`.`nombres`, ' ', `a`.`apellidos`) AS `agente_solicitado_nombre`,
(
SELECT
CONCAT(
`sigsiste_bd`.`agentes`.`nombres`,
' ',
`sigsiste_bd`.`agentes`.`apellidos`
)
FROM
`sigsiste_bd`.`agentes`
WHERE
(
`sigsiste_bd`.`agentes`.`id_agente` = `sc`.`id_agente_solicitante`
)
) AS `agente_solicitante_nombre`,
(
SELECT
`sigsiste_bd`.`agentes`.`imagen_perfil`
FROM
`sigsiste_bd`.`agentes`
WHERE
(
`sigsiste_bd`.`agentes`.`id_agente` = `sc`.`id_agente_solicitante`
)
) AS `imagen_perfil_solicitante`,
`a`.`imagen_perfil` AS `imagen_perfil_solicitado`,
DAYNAME(`sc`.`fecha_cobertura`) AS `nombre_dia`,
CONCAT(
CONVERT(
DATE_FORMAT(`sc`.`fecha_cobertura`, '%d') USING utf8mb4
),
' de ',
CONVERT(
MONTHNAME(`sc`.`fecha_cobertura`) USING utf8mb4
),
' de ',
CONVERT(
DATE_FORMAT(`sc`.`fecha_cobertura`, '%Y') USING utf8mb4
)
) AS `nombre_mes`,
'' AS `cambio_por`
FROM
(
`sigsiste_bd`.`solicitudes_cobertura` `sc`
LEFT JOIN `sigsiste_bd`.`agentes` `a`
ON
(
(
`a`.`id_agente` = `sc`.`id_agente_solicitado`
)
)
)
UNION ALL
SELECT
`sc`.`id` AS `id`,
`sc`.`id_agente_solicitado` AS `id_agente_solicitado`,
`sc`.`id_agente_solicitante` AS `id_agente_solicitante`,
`sc`.`fecha_devolucion` AS `fecha`,
`sc`.`horario_devolucion` AS `hora`,
`sc`.`pendiente` AS `pendiente`,
'3' AS `tipo`,
'Devoluciones' AS `grupo`,
'3' AS `grupo_numero`,
CONCAT(`a`.`nombres`, ' ', `a`.`apellidos`) AS `agente_solicitado_nombre`,
(
SELECT
CONCAT(
`sigsiste_bd`.`agentes`.`nombres`,
' ',
`sigsiste_bd`.`agentes`.`apellidos`
)
FROM
`sigsiste_bd`.`agentes`
WHERE
(
`sigsiste_bd`.`agentes`.`id_agente` = `sc`.`id_agente_solicitante`
)
) AS `agente_solicitante_nombre`,
(
SELECT
`sigsiste_bd`.`agentes`.`imagen_perfil`
FROM
`sigsiste_bd`.`agentes`
WHERE
(
`sigsiste_bd`.`agentes`.`id_agente` = `sc`.`id_agente_solicitante`
)
) AS `imagen_perfil_solicitante`,
`a`.`imagen_perfil` AS `imagen_perfil_solicitado`,
DAYNAME(`sc`.`fecha_devolucion`) AS `nombre_dia`,
CONCAT(
CONVERT(
DATE_FORMAT(`sc`.`fecha_devolucion`, '%d') USING utf8mb4
),
' de ',
CONVERT(
MONTHNAME(`sc`.`fecha_devolucion`) USING utf8mb4
),
' de ',
CONVERT(
DATE_FORMAT(`sc`.`fecha_devolucion`, '%Y') USING utf8mb4
)
) AS `nombre_mes`,
'' AS `cambio_por`
FROM
(
`sigsiste_bd`.`solicitudes_devoluciones` `sc`
LEFT JOIN `sigsiste_bd`.`agentes` `a`
ON
(
(
`a`.`id_agente` = `sc`.`id_agente_solicitado`
)
)
)
I have a view in SQL that after trying to open it gives me the following message: #1242 - Subquery returns more than 1 line.
How can I correct my query?
It is not possible to be sure, as you have not included nearly enough detail, but I suspect the error is being caused by the subquery for cambio_por as the other subqueries appear to be based on the PK -
(
SELECT
CONCAT(' ', `det`.`ingreso`)
FROM
(
`sigsiste_bd`.`planilla_horarios_det` `det`
LEFT JOIN `sigsiste_bd`.`planilla_horarios_cab` `cab`
ON
(
(
`cab`.`id_planilla_horarios_cab` = `det`.`id_planilla_horarios_cab`
)
)
)
WHERE
(
(
STR_TO_DATE(
CONCAT(
`cab`.`ano_correspondiente`,
',',
`cab`.`mes_correspondiente`,
',',
`det`.`dia`
),
'%Y,%m,%d'
) = `sc`.`fecha_solicitada`
) AND(
`sc`.`id_agente_solicitante` = `det`.`id_agente`
)
)
) AS `cambio_por`
to test you could try replacing it with an empty string, as you have for the other two selects -
'' AS `cambio_por`
Each of the three outer selects has two subqueries in the select list to retrieve values from sigsiste_bd.agentes based on sc.id_agente_solicitante. These should probably be replaced by another join.
...
(
SELECT
CONCAT(
`sigsiste_bd`.`agentes`.`nombres`,
' ',
`sigsiste_bd`.`agentes`.`apellidos`
)
FROM
`sigsiste_bd`.`agentes`
WHERE
(
`sigsiste_bd`.`agentes`.`id_agente` = `sc`.`id_agente_solicitante`
)
) AS `agente_solicitante_nombre`,
(
SELECT
`sigsiste_bd`.`agentes`.`imagen_perfil`
FROM
`sigsiste_bd`.`agentes`
WHERE
(
`sigsiste_bd`.`agentes`.`id_agente` = `sc`.`id_agente_solicitante`
)
) AS `imagen_perfil_solicitante`,
...
FROM
(
`sigsiste_bd`.`solicitudes_cambio_horario` `sc`
LEFT JOIN `sigsiste_bd`.`agentes` `a`
ON
(
(
`a`.`id_agente` = `sc`.`id_agente_solicitado`
)
)
)
would become
...
CONCAT(`agente_solicitante`.`nombres`, ' ', `agente_solicitante`.`apellidos`) AS `agente_solicitante_nombre`,
`agente_solicitante`.`imagen_perfil` AS `imagen_perfil_solicitante`,
...
FROM `sigsiste_bd`.`solicitudes_cambio_horario` `sc`
LEFT JOIN `sigsiste_bd`.`agentes` `a`
ON `a`.`id_agente` = `sc`.`id_agente_solicitado`
LEFT JOIN `sigsiste_bd`.`agentes` `agente_solicitante`
ON `agente_solicitante`.`id_agente` = `sc`.`id_agente_solicitante`
Your expression for nombre_mes can be simplified -
/* From */
CONCAT(
CONVERT(
DATE_FORMAT(`sc`.`fecha_cobertura`, '%d') USING utf8mb4
),
' de ',
CONVERT(
MONTHNAME(`sc`.`fecha_cobertura`) USING utf8mb4
),
' de ',
CONVERT(
DATE_FORMAT(`sc`.`fecha_cobertura`, '%Y') USING utf8mb4
)
) AS `nombre_mes`,
/* To */
CONVERT(DATE_FORMAT(`sc`.`fecha_solicitada`, '%d de %M de %Y') USING utf8mb4) AS `nombre_mes`,
SELECT
`BillNum`
, GROUP_CONCAT(CONCAT( `City` , ' / ' , `Region` , ' / ' , `StreetName` , ' / ' , `Closepoint`)) AS 'Address'
, GROUP_CONCAT(CONCAT('(', `ItemCount` ,')', `ItemName` , ' ' )separator ' ') AS OrderInfo
, CustomerPhone , `OrderTime`
FROM orderin
INNER JOIN `customers`
WHERE `CustomerPhone` = `customers`.`PhoneNumber`
AND `TableNum` = '0' AND DeleveryState = '0'
GROUP BY `BillNum`
ORDER BY `BillNum`;
Where is this wrong ? Why the address is multiplied ?
Add Distinct to your Group_Concat
Like
SELECT
`BillNum`
, GROUP_CONCAT(DISTINCT CONCAT( `City` , ' / ' , `Region` , ' / ' , `StreetName` , ' / ' , `Closepoint`)) AS 'Address'
, GROUP_CONCAT(DISTINCT CONCAT('(', `ItemCount` ,')', `ItemName` , ' ' )separator ' ') AS OrderInfo
, CustomerPhone , `OrderTime`
FROM orderin INNER JOIN `customers`
WHERE `CustomerPhone` = `customers`.`PhoneNumber`
AND `TableNum` = '0' AND DeleveryState = '0'
GROUP BY `BillNum`
ORDER BY `BillNum`
I have a serious problem with varchar in mysql.
This is my query :
SELECT ak.`address`, ak.lien1_amount, ak.`comp`, ak.`zestimate`, ak.`counvalue`, IFNULL(COALESCE(ak.comp, ak.zestimate, ak.counvalue), 0) AS cmazestcv, CEIL( CAST(ak.lien1_amount AS DECIMAL(10,5)) ) AS testnum
FROM allinformationk AS ak
LEFT JOIN `home_buyers_alias1` ON ak.`house id` = `home_buyers_alias1`.`house id`
WHERE ak.`is_deleted` = 'no' AND ( (CASE WHEN ak.`sale date 4` IS NOT NULL THEN ak.`sale date 4` WHEN ak.`sale date 3` IS NOT NULL THEN ak.`sale date 3` WHEN ak.`sale date 2` IS NOT NULL THEN ak.`sale date 2` ELSE ak.`sale date` END) IS NOT NULL)
AND ( CAST(IFNULL(COALESCE(ak.comp, ak.zestimate, ak.counvalue), 0) AS DECIMAL(10,5)) > CAST(ak.lien1_amount AS DECIMAL(10,5)) )
AND ak.lien1_amount IS NOT NULL
LIMIT 0, 10;
This is the result of my query :
The fields lien1_amount, comp, zestimate, counvalue are VARCHAR. This is why I am casting them to DECIMAL in my query. But still can't get it for testing as integer, you can see what lien1_amount gives in testnum column when I want to transform it to decimal.
How to change those varchar with comas to amount of money and test them ?
I can not do it since two days now.
If the said columns are of type varchar and hold numeric value always, then just replace the comma and use the result. No explicit cast is required.
And, if columns comp, zestimate, counvalue too contain comma as part of them, then apply replace on them too.
SELECT ak.`address`
, CEIL( replace( ifnull( ak.lien1_amount, 0 ), ',', '' ) ) as lien1_amount
, replace( ifnull( ak.`comp`, 0 ), ',', '' ) as `comp`
, replace( ifnull( ak.`zestimate`, 0 ), ',', '' ) as `zestimate`
, replace( ifnull( ak.`counvalue`, 0 ), ',', '' ) as `counvalue`
, replace( ifnull( COALESCE( ak.comp, ak.zestimate, ak.counvalue )
, 0 ), ',', '' ) AS cmazestcv
FROM allinformationk AS ak
LEFT JOIN `home_buyers_alias1`
ON ak.`house id` = `home_buyers_alias1`.`house id`
WHERE ak.`is_deleted` = 'no'
AND ak.lien1_amount IS NOT NULL
AND COALESCE( ak.`sale date 4`
, ak.`sale date 3`
, ak.`sale date 2`
, ak.`sale date` ) IS NOT NULL
AND replace(
IFNULL( COALESCE( ak.comp, ak.zestimate, ak.counvalue ), 0 ), ',', '' )
> replace( ak.lien1_amount, ',', '' )
LIMIT 0, 10;
Working on a sql query to show T_Temperatur and T_Badende_per_Time and the values. My sql query changes the comma to dot for the values with Cast, that is not the problem. The problem is that my sql query chose the values of the oppositite title, as you can see here:
SQL:
SELECT routines.date, routines.time,
SUM( IF( measurements.title = 'T_Temperatur', CAST( REPLACE( routines.value, ',', '.' ) AS DECIMAL( 18, 2 ) ), 0 ) ) AS T_Temperatur,
SUM( IF( measurements.title = 'T_Badende_per_Time', CAST( REPLACE( routines.value, ',', '.' ) AS DECIMAL( 18, 2 ) ), 0 ) ) AS Badende,
SUM( IF( measurements.title = 'T_Luft_temperatur', CAST( REPLACE( routines.value, ',', '.' ) AS DECIMAL( 18, 2 ) ), 0 ) ) AS Luft_Temp
FROM routines
INNER JOIN measure_routine ON routines.id = measure_routine.routine_id
INNER JOIN measurements ON measure_routine.measure_id = measurements.id
GROUP BY routines.date, routines.time
ORDER BY routines.date, routines.time;
My database is build up with
routines:
measure_routine:
measurements:
Swap the parameters in the IF() function, you return 0 if the condition is true!
IF(expr1,expr2,expr3)
If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns expr2; otherwise it returns expr3.
SELECT routines.date, routines.time,
SUM(IF(measurements.title='T_Temperatur', CAST(REPLACE(routines.value,',','.' ) AS DECIMAL(18,2)), 0)) AS T_Temperatur,
SUM(IF(measurements.title='T_Badende_per_Time', CAST(REPLACE(routines.value,',','.') AS DECIMAL(18,2)), 0)) AS Badende
FROM routines
INNER JOIN measure_routine ON routines.id = measure_routine.routine_id
INNER JOIN measurements ON measure_routine.measure_id = measurements.id
order by routines.date, routines.time
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