How can I find a string separated by a space in SQL - sql

I am trying to find a way where I can skim out records of customers where 'First Name' and 'Middle Name' has been entered in the first_name column in the customer detail table. For examples
first_name, Last_name, mobile_no
Mary Jane Smith 0400000000
Shane Angus John 0400000000
Rudy Gill 0401111111
Rachel Rose
from the above examples I only want to find records
Mary Jane Smith 0400000000
Shane Angus John 0400000000

You can use like:
select t.*
from t
where first_name like '% %';
Note: This just checks for a space. It does not guarantee that one of the names is a middle name.

here's another solution for you if you want to get more complex and account for the middle name.
create table test (first_name nvarchar(50), middle_name nvarchar(50), last_name nvarchar(75), mobile_no nvarchar(10))
insert test
select 'mary jane', null, 'smith', '0400000000'
union all
select 'shane angus', null, 'john', '0400000000'
union all
select 'rudy', 'jacob', 'gill', '0401111111'
union all
select 'rachel', 'liza', 'rose', '0400000000'
select *
from test
where middle_name is null and charindex(char(32),first_name) > 0
this won't help you though if the first name is double-worded like Bobby Jo hence the middle name check.

Related

Why is no data being returned

I am trying to find majors that end with S, but no data is being returned
create table Student
(sid char(10) primary key,
sname varchar(20) not null,
gpa float,
major char(10),
dob DATE);
insert into Student values('111', 'Joe', 3.5 , 'MIS', '01-AUG-2000');
insert into Student values('222', 'Jack', 3.4 , 'MIS', '12-JAN-1999');
insert into Student values('333', 'Jill', 3.2 , 'CS', '15-MAY-1998');
insert into Student values('444', 'Mary', 3.7 , 'CS', '17-DEC-2001');
insert into Student values('555', 'Peter', 3.8 , 'CS', '19-MAR-1999');
insert into Student values('666', 'Pat', 3.9, 'Math', '31-MAY-2000');
insert into Student values('777', 'Tracy', 4.0, 'Math', '18-JUL-1997');
SELECT * FROM STUDENT
WHERE MAJOR LIKE '%S'
This doesn't work on livesql (oracle (PL-SQL) based but works on T-SQL).
This is the error message: 'No data found'
Your CHAR(10) will always contain 10 characters so it is going to be padded with space characters. Change to VARCHAR2(10) and it will work. I'm assuming Oracle since you didn't specify which database. But VARCHAR(10) should work with T-SQL.
If you can't (or won't) modify datatype to varchar2 (not varchar as Stilgar suggested), then trimming the column might help:
SQL> select * from student
2 where trim(major) like '%S';
SID SNAME GPA MAJOR DOB
---------- -------------------- ---------- ---------- --------
111 Joe 3,5 MIS 01.08.00
222 Jack 3,4 MIS 12.01.99
333 Jill 3,2 CS 15.05.98
444 Mary 3,7 CS 17.12.01
555 Peter 3,8 CS 19.03.99

SQL Substring Functions

I have a column named full name. I want to split them into two columns, first name and last name.
I am having a trouble with a persons with two first names. If the first name encounters a space it was considered last name.
I want this:
Full name : John Michael Smith
Firstname: John Michael
Lastname: Smith
However, I am getting:
Firstname: John
Lastname: Michael Smith
Try:
declare #n varchar(max) = 'John Michael Smith'
select REVERSE(SUBSTRING(REVERSE(#n), CHARINDEX(' ', REVERSE(#n)), 100)) FirstName
Check the below link:
SQL SERVER – Reverse String Word By Word – Part 2
You can split the string by checking for the index of last space and using it with LEFT and RIGHT function.
DECLARE #name varchar(100)= 'John Michael Smith'
SELECT LEFT(#name,LEN(#name)-CHARINDEX(' ',REVERSE(#name))) AS [Firstname],RIGHT(#name,CHARINDEX(' ',REVERSE(#name))) AS [LastName]
--Create table from below script
create table users(id int IDENTITY(1,1) PRIMARY KEY, name varchar(50));
--Insert Record for query for testing
insert into users(name)
values('John Abraham'),
('John Mark Abraham'),
('John Vens Abraham'),
('John Abraham');
--Run below query for getting all inserted records.
select * from users;
--Run below query for getting first and last name from name
select id , name, SUBSTRING(name,0, CHARINDEX(last_name,name)) as first_name, last_name from
(
select id, name, REVERSE(SUBSTRING(REVERSE(name),0,CHARINDEX(' ',REVERSE(name)))) as last_name from users
) as A
You can hi-jack 'parsename'. This only works up to 4 intervals but a nice option;
declare #name varchar(100)
set #name='John Michael Smith'
select PARSENAME(REPLACE(#name,' ','.'),1) -- returns Smith
select PARSENAME(REPLACE(#name,' ','.'),2) -- returns Micheal
select PARSENAME(REPLACE(#name,' ','.'),3) -- Returns John
select PARSENAME(REPLACE(#name,' ','.'),4) -- returns NULL

Check address voor 2 properties and display in same row

From the Persons table I would like to get the following output:
Number FirstName AddressAvenue AddressFloor
----------------------------------------------
1 David Long Avenue 5th Floor
2 Bob Short Avenue NULL
3 Peter Middle Avenue 1st Floor
(Apparently, Bob his address does not contain a Floor number).
I thought I would get this by running the following query:
select
p.Number
p.FirstName
, case when (p.Street like '%Avenue%') then p.Street end as AddressAvenue
, case when (p.Street like '%Floor%') then p.Street end as AddressFloor
from
#persons
;
However, the output is as follows:
Number FirstName AddressAvenue AddressFloor
----------------------------------------------
1 David Long Avenue NULL
2 Bob Short Avenue NULL
3 Peter Middle Avenue NULL
1 David NULL 5th Floor
3 Peter NULL 1st Floor
Question How can I get both Address and Floor on the same line?
Any help is greatly appreciated!
Try this bad boy
CREATE TABLE #persons
(
Number INT
,FirstName VARCHAR(10)
,Street VARCHAR(50)
)
INSERT #persons
VALUES
(1, 'David', 'Long Avenue'),
(2, 'Bob', 'Short Avenue'),
(3, 'Peter', 'Middle Avenue'),
(1, 'David', '5th Floor'),
(3, 'Peter', '1st Floor')
--This is the code you really want, I just needed the rest to test it and make sure it worked
SELECT DISTINCT
z.Number
,z.FirstName
,(SELECT p.Street FROM #persons p where p.Street LIKE '%Avenue%' AND p.Number = z.Number)
,(SELECT p.Street FROM #persons p where p.Street LIKE '%Floor%' AND p.Number = z.Number)
FROM #persons z
DROP TABLE #persons
Results in the following:

Distinct over one column with value comparing on another column ICriteria NHibernate

I have table and object called Person. I have problem to create a distinct (over column "lastname") criteria. I want to get only the oldest Person with distinct lastnames.
For example i have (properties: firstname, lastname, age):
John Smith, 52
Jessica Smith, 45
Ann Pit, 21
Brad Pit, 30
Can anybody help me to create criteria which result i get Person object with John Smith and Brad Pit?
Probably the best approach here is to use EXISTS to filter the result set, first a SQL example to get the logic correct:
DECLARE #Person TABLE (
Id INT,
Firstname VARCHAR(20),
Lastname VARCHAR(20),
Age INT
)
INSERT INTO #Person VALUES (1, 'Brad', 'Pitt', 42)
INSERT INTO #Person VALUES (2, 'Angelina', 'Pitt', 45)
INSERT INTO #Person VALUES (3, 'John', 'Smith', 50)
INSERT INTO #Person VALUES (4, 'Jane', 'Smith', 55)
SELECT P.* FROM #Person P
WHERE EXISTS(
SELECT SUB.LastName, MAX(SUB.Age) as Age FROM #Person SUB
GROUP BY SUB.LastName
HAVING SUB.LastName = P.LastName AND MAX(SUB.Age) = P.Age)
This yields the following results which is as expected:
Id Firstname Lastname Age
-------------------------------
2 Angelina Pitt 45
4 Jane Smith 55
Now to convert to nHibernate, this effectively builds the same query as above:
var subQuery = DetachedCriteria.For<Person>("SUB")
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("LastName"), "Lastname")
.Add(Projections.Max("Age"), "Age"))
.Add(Restrictions.EqProperty(Projections.Max("Age"), "P.Age")
.Add(Restrictions.EqProperty("LastName", "P.LastName"));
return session.CreateCriteria<Person>("P")
.Add(Subqueries.Exists(subQuery))
.List<Person>();

SQL SELECT distinct rows from a table by multiple columns ignoring columns order (significance)

I have a table People (First_Name, Last_Name). This table has records that are duplicated as in the example (not all rows are duplicated):
First_Name Last_Name
John Smith
Alec Baldwin
Smith John
Angelo Gordon
Mary Bush
Bush Mary
How do I select all distinct people? In the final output of the query John Smith should appear only once (it’s not import if in the final query there is John Smith or Smith John).
Thank you.
Just pick an ordering and apply it across everyone. Then use a union that will eliminate duplicates anyway
select FirstName,LastName from People where FirstName <= LastName
union
select LastName,FirstName from People where LastName < FirstName
This is one way to do it using pretty much any SQL flavor.
DECLARE #Names TABLE (
First_Name VARCHAR(32)
, Last_Name VARCHAR(32)
)
INSERT INTO #Names VALUES ('John', 'Smith')
INSERT INTO #Names VALUES ('Alec', 'Baldwin')
INSERT INTO #Names VALUES ('Smith', 'John')
INSERT INTO #Names VALUES ('Angelo', 'Gordon')
INSERT INTO #Names VALUES ('Mary', 'Bush')
INSERT INTO #Names VALUES ('Bush', 'Mary')
Using a JOIN
SELECT n1.*
FROM #Names n1
LEFT OUTER JOIN #Names n2 ON n2.First_Name = n1.Last_Name
AND n2.Last_Name = n1.First_Name
AND n2.First_Name < n1.First_Name
WHERE n2.First_Name IS NULL
or NOT EXISTS
SELECT n1.*
FROM #Names n1
WHERE NOT EXISTS (
SELECT *
FROM #Names n2
WHERE n2.First_Name = n1.Last_Name
AND n2.Last_Name = n1.First_Name
AND n2.First_Name < n1.First_Name
)
Sorry was missundertanding your question on the first try...
WITH People (Firstname, Lastname)
AS
(
SELECT 'John' AS Firstname, 'Smith' AS Lastname UNION
SELECT 'John' AS Firstname, 'Smith' AS Lastname UNION
SELECT 'Alec' AS Firstname, 'Baldwin' AS Lastname UNION
SELECT 'Smith' AS Firstname, 'John' AS Lastname UNION
SELECT 'John' AS Firstname, 'Smith' AS Lastname UNION
SELECT 'Angelo' AS Firstname, 'Gordon' AS Lastname UNION
SELECT 'Mary' AS Firstname, 'Bush' AS Lastname UNION
SELECT 'Bush' AS Firstname, 'Mary' AS Lastname
)
SELECT p1.* FROM People p1
LEFT OUTER JOIN People p2 ON p2.Firstname = p1.Lastname AND p2.Lastname = p1.Firstname AND p2.Firstname < p1.Firstname
WHERE p2.Firstname IS NULL
Here's a solution which uses Oracle functions. Other flavours of SQL will have the same or very similar functions:
SQL> select * from t23
2 /
FIRST_NAME LAST_NAME
------------------------------ ------------------------------
John Smith
Alec Baldwin
Smith John
Angelo Gordon
Mary Bush
Bush Mary
6 rows selected.
SQL> select distinct least(first_name, last_name)
2 , greatest(first_name, last_name)
3 from t23
4 /
LEAST(FIRST_NAME,LAST_NAME) GREATEST(FIRST_NAME,LAST_NAME)
------------------------------ ------------------------------
Alec Baldwin
Bush Mary
John Smith
Angelo Gordon
SQL>
I think this might work in MS-SQL
select * from People
where (FirstName + "," + LastName) <> (LastName + "," + FirstName)
Another sugestion
Temporary Table:
DECLARE #Names TABLE (
First_Name VARCHAR(32)
, Last_Name VARCHAR(32)
)
INSERT INTO #Names VALUES ('John', 'Smith')
INSERT INTO #Names VALUES ('Alec', 'Baldwin')
INSERT INTO #Names VALUES ('Smith', 'John')
INSERT INTO #Names VALUES ('Angelo', 'Gordon')
INSERT INTO #Names VALUES ('Mary', 'Bush')
INSERT INTO #Names VALUES ('Bush', 'Mary')
Using CASE
SELECT DISTINCT
CASE WHEN First_Name <= Last_Name THEN First_Name ELSE Last_Name END AS First_Name,
CASE WHEN First_Name <= Last_Name THEN Last_Name ELSE First_Name END AS Last_Name
FROM #Names