Check if an employee email contains his name - not a case sensitive - mysql

I would like to display the name and the email associated with it when the employee name is contained within the email. A user can have more than one email.
employee
id name
1 Steve Been
2 Rob Kem
3 Bob Kimi
Emails
emplyee_id email
1 steve#domain.com
1 007#domain.com
1 Been#domain.com
2 Robkem#domain.com
2 Rob.Kem#domain.com
3 Boooob#domain.com
3 kimi#domain.com
The query should not be case sensitive. I would like this query to show me something like:
name email
Steve Been steve#domain.com
Steve Been Been#domain.com
Rob Kem Robkem#domain.com
Rob Kem Rob.Kem#domain.com
Bob Kimi kimi#domain.com
I tried this but I got empty output:
select empl.Name as 'employee Name', em.email as 'Product Name'
from email em JOIN employee empl
ON em.employee_id = empl.ID
WHERE FIND_IN_SET(LOWER(empl.Name),LOWER(em.Name))

Try
SELECT e.name,
m.email
FROM emails m JOIN
employee e ON m.emplyee_id = e.id
WHERE INSTR(m.email, SUBSTRING_INDEX(e.name, ' ', 1)) > 0
OR INSTR(m.email, SUBSTRING_INDEX(e.name, ' ', -1)) > 0
SQLFiddle
INSTR() is case insensitive unless one of the stings is a binary string, but you can always add LOWER() for a good measure.
UPDATE: As per your additional request you can do that with a query like this
SELECT name,
total,
matched,
total - matched unmatched
FROM (
SELECT e.name,
COUNT(*) total,
SUM(CASE WHEN INSTR(m.email, SUBSTRING_INDEX(e.name, ' ', 1)) > 0
OR INSTR(m.email, SUBSTRING_INDEX(e.name, ' ', -1)) THEN 1 ELSE 0 END) matched
FROM emails m JOIN
employee e ON m.emplyee_id = e.id
GROUP BY e.id, e.name) q
SQLFiddle

Related

SQL Select with Conditional Fields (Subquerys maybe?)

I'm trying to set up an SQL View that returns all details of a contact. Name and Last name are saved in a Table "Person", the contact info is saved in "contact" and the type of contact info (email, phone 1, phone2) is saved in "contact_types".
I want to return all the information in 1 row but I can't really figure it out. So far my best result is with:
SELECT
Person.ID, Person.Title, Person.Firstname, Person.Lastname,
( SELECT MAX(ContactInfo.InfoText) FROM ContactInfo WHERE ContactInfo.ContactTypID = '1' AND ContactInfo.PersonID = Person.ID ) AS Phone_Business,
( SELECT MAX(ContactInfo.InfoText) FROM ContactInfo WHERE ContactInfo.ContactTypID = '2' AND ContactInfo.PersonID = Person.ID ) AS Phone_Private,
( SELECT MAX(ContactInfo.InfoText) FROM ContactInfo WHERE ContactInfo.ContactTypID = '3' AND ContactInfo.PersonID = Person.ID ) AS Phone_Mobile,
( SELECT MAX(ContactInfo.InfoText) FROM ContactInfo WHERE ContactInfo.ContactTypID = '5' AND ContactInfo.PersonID = Person.ID ) AS Email
FROM Person
This statement results in duplicate outputs - 4 identical rows, even with MAX(). It is apparently one row per subquery. How can I only receive 1 row per ID?
I'm quite new to SQL, any suggestions would be helpful!
Edit:
Sample Data:
Table Person:
ID
Title
Firstname
Lastname
1
Mr.
Tom
Selleck
2
Mr.
Fred
Miller
Table ContactInfo
PersonID
InfoText
ContactTypeID
1
tom.selleck#gmail.com
5
2
+1 12345 678
1
1
+1 98765 432
2
Table ContactTypeID
ID
InfoText
1
phone_business
2
phone_private
5
email
Expected Result:
ID
Title
Firstname
Lastname
Phone_Business
Phone_Private
Phone_Mobile
Email
1
Mr.
Tom
Selleck
NULL
+1 98765 432
NULL
tom.selleck#gmail.com
2
Mr.
Fred
Miller
+1 12345 678
NULL
NULL
NULL
It works so far, but I'd get each row 4 times.
You can do it like this:
SELECT P.ID, P.Title, P.Firstname, P.Lastname,
MAX(CASE WHEN C.ContactTypeID = '1' THEN C.InfoText END) AS Phone_Business,
MAX(CASE WHEN C.ContactTypeID = '2' THEN C.InfoText END) AS Phone_Private,
MAX(CASE WHEN C.ContactTypeID = '3' THEN C.InfoText END) AS Phone_Mobile,
MAX(CASE WHEN C.ContactTypeID = '5' THEN C.InfoText END) AS Email
FROM Person P
LEFT JOIN ContactInfo C
ON P.ID=C.PersonID
GROUP BY P.ID, P.Title, P.Firstname, P.Lastname;
Just a single LEFT JOIN between Person table and ContactInfo. The Person table here acts as a reference table. Then use MAX() with CASE expression (also possible with GROUP_CONCAT()) in SELECT.
Here's a demo fiddle

multiple values in 1 column when you join 2 tables

table 1 - employee
id empname
--------------
1 andy
2 brady
table 2 - employee phone numbers
id number empid
----------------
1 1111 1
2 2222 2
3 3333 1
4 4444 1
Need a sql query to display the following
id empname numbers
------------------
1 andy 1111,3333,4444
2 brady 2222
If you are using MySQL, you can use GROUP_CONCAT funcion, that basically concatenate every value composing the group. You could try this:
SELECT EMP.ID,
EMP.EMPNAME,
GROUP_CONCAT(EPH.NUMBER) AS NUMBERS
FROM EMPLOYEE EMP
JOIN EMPLOYEE_PHONE EPH
ON EMP.ID = EPH.EMPID
GROUP BY EMP.ID
Also, if you want to separate your values with something different of a "," you can add the syntax SEPARATOR " " after the column inside group concat, if you want to separate with spaces in this particular example
if you use SQL SERVER I think this will do it for you, if not maybe a close guess without data. But! I used STUFF and selected the Number and split them by , and ordered it
SELECT
t1.ID,t2v1.empname,
STUFF((SELECT ',' + t2v2.number
FROM Table2 t2v2
WHERE t2v2.ID = t2v1.ID
ORDER BY number
FOR XML PATH('')), 1, 1, '') [numbers]
FROM Table1 t1
inner join table2 t2v1 on t1.id = t2v1.id
GROUP BY t1.ID, t1.Name
ORDER BY 1
Try this:
SELECT e.id, e.name, CONCATENATE(ep.number, ',') as phonelist
FROM Employees e INNER JOIN EmployeePhone ep ON e.id = ep.empid
Reference Doc: http://www.peteonsoftware.com/index.php/2009/12/11/creating-a-comma-separated-list-from-a-sql-grouping/

Combine 2 values to 1 column MySQL

Code:
SELECT s.*, k.address FROM student s
INNER JOIN address k
ON instr(s.fulladdress, k.address) > 0
WHERE j.phonetic like '%california%'
This result will display 2 rows with 2 parts of address:
30,Andre Hans, Address 1 Address 2,class IBA1001, Address 1
30,Andre Hans, Address 1 Address 2,class IBA1001, Address 2
I want to display it in 1 row:
30,Andre Hans, Address 1 Address 2,class IBA1001, Address 1 | Address 2
How i can do that?
Use group by and group_concat:
SELECT s.*, group_concat(k.address separator ' | ') FROM student s
INNER JOIN address k
ON instr(s.fulladdress, k.address) > 0
WHERE j.phonetic like '%california%'
GROUP BY s.col1, s.col2 .... -- all the columns in table student

looking for a field name that contains specific data (mySql)

i got table named "teachers_db" with field names:
teacher_name
instrument1
instrument2
payment1
payment2
In my program i get list of teachers and what instrument they are teaching.
e.i:
Mathew - piano
Mathew - drums
Adam - guitar
I want to phrase a code line in mySQL that get a teacher_name and instrument (instrument1 = "piano" or instrumnet2 = "drums" and so on), and return the payment for it (payment1 if its a piano, playment2 if its a drums).
i'm hammering my head with this problem, please help :)
One way to get the result is to use two separate queries, combined with a UNION ALL operator. For example:
SELECT q.teacher_name
, q.instrument1 AS instrument
, q.payment1 AS payment
FROM teachers_db q
WHERE q.instrument1 <> ''
UNION ALL
SELECT r.teacher_name
, r.instrument2 AS instrument
, r.payment2 AS payment
WHERE r.instrument2 <> ''
ORDER BY 1,2
Another approach:
SELECT t.teacher_name
, CASE i.n WHEN 1 THEN t.instrument1 WHEN 2 THEN t.instrument2 END AS instrument
, CASE i.n WHEN 1 THEN t.payment1 WHEN 2 THEN t.payment2 END AS payment
FROM (SELECT 1 AS n UNION ALL SELECT 2) i
CROSS
JOIN teachers_db t
HAVING instrument <> ''
ORDER BY 1,2

Multi-Join Query, Pivot? Troubles

Thank you in advance for anyone who helps with this. I know i've seen this done before without too much pain but cant seem to find the solution
My database looks something like:
`tbl_user:
----------
id ( pkey )
email
fName
lName
tbl_userSparseType:
-------------------
id ( pkey )
varName
displayName
tbl_userSparse:
---------------
id ( pkey )
value ( Value of Sparse Type )
user_id ( => tbl_user.id )
userSparseType_id ( => tbl_userSparseType.id )
with sample data:
tbl_user:
(id, email, fName, lName)
1 Bob#example.com Billy Bob
2 Betty#example.com Betty Sue
3 Beam#example.com Jim Beam
tbl_userSparseType:
(id, varName, displayName)
1 fullName Full Name
2 dayPhone Day Phone
3 nightPhone Night Phone
4 cellPhone Cell Phone
5 homeAddr Home Address
tbl_userSparse:
(id, value, user_id, userSparseType_id)
1 Billy John Bob 1 1
2 James B. Beam 3 1
3 123-234-3456 1 2
4 234-345-4567 1 4
5 24 Best st. 2 5
6 456-567-6789 3 3
I tried doing two left joins, but this gave me a tbl_user row for each sparse entry like:
(id, email, fName, lName, displayName, value)
1,"Bob#example.com","Billy","Bob","Full Name","Billy John Bob"
1,"Bob#example.com","Billy","Bob","Day Phone","123-234-3456"
1,"Bob#example.com","Billy","Bob","Cell Phone","234-345-4567"
And despite a few 45 or so minute sessions of looking, I cant find a way to get something more like the following without explicitly naming the columns, I need a dynamic way to only pull all display names that apply to the subset of tbl_user rows being queried:
WHERE tbl_user.id IN (1,2)
id | email | fName | lName | Full Name, | Day Phone | Cell Phone |
Home Address
-------------------------------------------------------------------------------------------------------
1 | Bob#example.com | Billy | Bob | Billy John Bob | 123-234-3456 | 234-345-4567 |
2 | Betty#example.com | Betty | Sue | | | | 24 Best St.
Thanks again in advance, I'm hoping this can be done without too much fuss. :\
Unfortunately MySQL does not have a PIVOT function which is basically what you are trying to do. So you will need to use an aggregate function with a CASE statement. If you know the number of columns, then you can hard-code the values:
select u.id,
u.email,
u.fname,
u.lname,
max(case when t.displayname = 'Full Name' then us.value end) FullName,
max(case when t.displayname = 'Day Phone' then us.value end) DayPhone,
max(case when t.displayname = 'Cell Phone' then us.value end) CellPhone,
max(case when t.displayname = 'Home Address' then us.value end) HOmeAddress
from tbl_user u
left join tbl_userSparse us
on u.id = us.user_id
left join tbl_userSparseType t
on us.userSparseType_id = t.id
where u.id in (1, 2)
group by u.id, u.email, u.fname,u.lname;
See SQL Fiddle With Demo
Now if you want to perform this dynamically, meaning you do not know ahead of time the columns to transpose, then you should review the following article:
Dynamic pivot tables (transform rows to columns)
Your code would look like this:
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when t.displayname = ''',
t.displayname,
''' then us.value end) AS ',
replace(t.displayname, ' ', '')
)
) INTO #sql
FROM tbl_userSparse us
left join tbl_userSparseType t
on us.userSparseType_id = t.id;
SET #sql = CONCAT('SELECT u.id, u.email, u.fname, u.lname, ', #sql, '
from tbl_user u
left join tbl_userSparse us
on u.id = us.user_id
left join tbl_userSparseType t
on us.userSparseType_id = t.id
where u.id in (1, 2)
group by u.id, u.email, u.fname, u.lname');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
See SQL Fiddle with Demo