Oracle SQL - combine two columns - sql

How can I combine two columns in Oracle SQL without using CASE?
I have to combine FirstName and LastName in the same row.
I have a table as below:
FirstName LastName
-----------------------
Ken Chan
John Ng
Joe Lam
The data type of these columns is VARCHAR2.
I try to apply the code as follow
SELECT
CONCAT(LastName, ‘,’, FirstName) AS FullName
FROM
LIST
ORDER BY
Place;
SELECT
LastName, ‘,’, FirstName AS FullName
FROM
LIST
ORDER BY
Place;
But both of them result in the the same error
ORA-00909: invalid number of arguments.
May I also ask how can I not adding the ‘,’ while there is missing LastName or FirstName?
Such as not adding ‘,’ when there is only having LastName Chan. The FullName only display as Chan but not ,Chan.
Thanks a lot for helping me.

Use Concatenation Operator that is ||. It concatenates character strings and results in another character string.
To make , comma optional in case if any of the LastName or firstName field is empty or null, use CASE statement.
Solution for your problem:
SELECT LastName || (CASE WHEN LastName IS NOT NULL AND FirstName IS NOT NULL THEN ',' END) || FirstName as FullName
FROM LIST
ORDER BY place;
Working Example: db<>fiddle Link
For more info on Concatenation Operator follow below link to official docs:
https://docs.oracle.com/cd/B19306_01/server.102/b14200/operators003.htm

Oracle's implementation of the concat() function only permits 2 parameters, and you have tried 3, that is why you got the error message.
It is simpler, in Oracle, to use the more traditional double pipe operator to form a concatenated string.
SELECT LastName || ‘,’ || FirstName as FullName
from LIST
order by Place;

Related

Update Column from Columns within same table using SQLite

I’m trying to update an email address value from users first- and lastname within the same table.
Pattern for generated Mail: <Firstname>.<Lastname>#test.org
Example Table “Persons”:
Firstname Lastname email
Henley Figueroa none#none.com
Samina Morrison none#none.com
Dev Rowe none#none.com
Wished result for table “Persons”:
Firstname Lastname email
Henley Figueroa Henley.Figueroa#test.org
Samina Morrison Samina.Morrison#test.org
Dev Rowe Dev.Rowe#test.org
SQL Code
UPDATE Persons
SET
email = (SELECT FirstName || "." || LastName ||"#"||"test.org" FROM Persons)
Actual result for table “Persons”:
Firstname Lastname email
Henley Figueroa Henley.Figueroa#test.org
Samina Morrison Henley.Figueroa#test.org
Dev Rowe Henley.Figueroa#test.org
Only the first record of the returned result table is used over and over. Why?
If I ommit the SELECT:
UPDATE Persons
SET
email = FirstName || "." || LastName ||"#"||"test.org"
I get the expected result.
Referring to your answers, I'm extending my question with an example of two tables. One with only names, the second for mail addresses.
Table Persons:
ID*
Firstname
Lastname
1
Henley
Figueroa
2
Samina
Morrison
3
Dev
Rowe
Table Addresses:
ID*
email
1
wrong#wrong.ng
2
wrong#wrong,ng
3
wrong#wro.ng
UPDATE Addresses
SET email = (SELECT Firstname ||"."|| Lastname || "#test.org"
FROM Persons WHERE Persons.id = Addresses.id)
Demo
Here the UPDATE with SET and SELECT works (Every person gets a unique mail address). Shouldn’t I get the same problem here?
From the output of SELECT I see that I get again (as expected) three records.
You have the right syntax for your problem. So the question is why does this not do what you want?
UPDATE Persons
SET email = (SELECT FirstName || "." || LastName ||"#"||"test.org"
FROM Persons
);
In fact, this should produce an error in any SQL engine -- although SQLite can be a bit lax about such errors. Why? The SET is expecting a single value. This code has a subquery that returns three values.
Note: The SQL Fiddle does show that SQLite accepts this syntax. Argggh! You can switch this to Postgres to see the error. With some modifications, to the create code you could also see the same error (subquery returns more than one row) using SQL Server or Oracle or just about any database.
Apparently, SQLite is just arbitrarily choosing one of those values -- the one that it first encounters. And this is the same value for all three rows.
You already know that a subquery is not correct here. You have the correct code in your question.
From Subquery Expressions:
A SELECT statement enclosed in parentheses is a subquery. All types of
SELECT statement, including aggregate and compound SELECT queries
(queries with keywords like UNION or EXCEPT) are allowed as scalar
subqueries. The value of a subquery expression is the first row of
the result from the enclosed SELECT statement. The value of a
subquery expression is NULL if the enclosed SELECT statement returns
no rows.
So the value you get by the subquery is the first row of the rows returned.
Of course, you don't need the SELECT statement.
This is a simple UPDATE statement that involves only the values of the columns of the current row:
UPDATE Persons
SET email = FirstName || '.' || LastName || '#' || 'test.org'
See the demo.
Results:
Firstname
Lastname
email
Henley
Figueroa
Henley.Figueroa#test.org
Samina
Morrison
Samina.Morrison#test.org
Dev
Rowe
Dev.Rowe#test.org
For the 2nd query with the 2 tables:
Shouldn’t I get the same problem here?
No, because the subquery is a correlated subquery, which returns for each row in the table Addresses only 1 row (provided there are no duplicate ids in Persons), the row which matches the condition Persons.id = Addresses.id.
If there is no row that matches the condition then it will return NULL.

Matching pattern in SQL

I have two tables and need to match all records by name. The problem is that in one table name format is FirstName LastName, in another table - LastName FirstName, and I cannot split into separate columns because some records might have few first names or last names, so I don't know where first or last name ends or starts.
Eg. in first table I have John Erick Smith and need to join all records from another table where the name is Smith John Erick.
Any solution in SQL?
I think you can use string functions to get the piece of string (in 'John Erick Smith' type column) after the last space as a surname and stick it to front. Then you could compare the strings. That is assuming you don't have spaces in surnames.
Here is MSDN article on how to do it.
DECLARE #string nvarchar(max) = 'FirstName SecondName Surname'
SELECT RIGHT(#string, NULLIF(charindex(' ', REVERSE(#string)),0)) + ' ' +
REVERSE(RIGHT(REVERSE (#string), len(#string) - NULLIF(charindex(' ', REVERSE(#string)),0)))
Returns:
Surname FirstName SecondName
Verify first if you still have other tables with "FirstName" and "LastName" that you can use instead of using the field with "FirstName LastName". Normally Oracle has this kind of tables use for persons/employees. You may have something like this.
But if the "LastName FirstName" uses "," (comma) in its data then you can do a substring to get the LastName from the FirstName.
Or another alternative is by using their IDs (eg. employee IDs) [if only available].

String concatenation as an alias displays 0 in SQLite?

I was looking at this tutorial from W3Schools, where they combine address, zip code and country together as a single column "Address". So I've been playing with the Northwind DB and wanted to do the same thing for employee name:
SELECT EmployeeID, FirstName +" "+ LastName AS Name FROM Employees;
But all I get is 0's in the "Name" column. I figure SQLite has implicitly converted the string to integer, but it doesn't make sense...
Replace + with || wich is the string concatenation operator in SQLite and many other databases.
SELECT EmployeeID, FirstName || ', ' || LastName AS Name FROM Employees;

is there any `backspace` character in mssql for string?

Below is the query to form a string containing company details by concatenating Name, address1 and address2. Here I am using the ISNULL() function to concatenate an empty string ('') if the column is null.
select Name+' ,'+isnull(Address1,'')+' ,'+isnull(Address2,'') as compDeatils
from tableCompany where ID = 4
This query's issue is in the case where Address1 or Address2 is null, it will concatenate a comma before the empty space which I don't want.
For example, if Address1 and Address2 are NULL then the result will be name,,.
How i can overcome this?
Is there a backspace character in mssql?
i got the answer it is simple logic.. add commas within the ISNULL() function
select Name+isnull(','+Address1,'')+isnull(','+Address2,'') as compDeatils
from tableCompany where ID = 4
Note: Name will not give NULL in my case. in case name also null this answer is not applicable.

Basic SQL Query, I am newbie

I just started my database and query class on Monday. We met on Monday and just went over the syllabus, and on Wednesday the network at school was down so we couldn't even do the power point lecture. Right now I am working on my first homework assignment and I am almost finished but I am having trouble on one question.
Here is is...
Write a SELECT statement that returns one column from the Customers table named FullName that joins the LastName and FirstName columns.
Format the columns with the last name, a comma, a space, and the first name like this:
Doe, John
Sort the result set by last name in ascending sequence.
Return only the contacts whose last name begins with letters from M to Z.
Here is what I have so far...
USE md0577283
SELECT FirstName,LastName
FROM Customers
ORDER BY LastName,FirstName
My question is how do I format is Lastname, FirstName like the professor wants and how do I only select names M-Z?
If someone could point me in the right direction I would greatly appreciate it.
Thank you.
PS With all do respect, I didn't ask for the answer I asked for a nudge in the right direction so why the down vote guys?
USE md0577283
SELECT LastName + ', ' + FirstName FullName
FROM Customers
WHERE LastName LIKE '[M-Z]%'
ORDER BY LastName,FirstName
You want to add two things: create an expression to return the name in the requested format
(LastName + ", " + FirstName as Name)
USe a "where clause" to filter what is returned: where LastName >= "M" and LastName <= "Z" perhaps.
Simply write like this.
If you want to get names from m to z.
SELECT LastName, FirstName
FROM Customers
WHERE FirstName between 'M%' and 'Z%'
ORDER BY LastName, FirstName
If you want to get names from m and z only.
SELECT LastName, FirstName
FROM Customers
WHERE FirstName LIKE 'M%' OR FirstName LIKE 'Z%'
ORDER BY LastName, FirstName