Need a query for many to many relationship in MYSQL - mysql

Below is the table structure:
I have three tables : employee, skill and employee_skills.
Employee: id, firstname, lastname, etc.....
Skill : id, title, description
Emplyoee_skills : id, employee_id (FK of employee table), skill_id(FK of skill table)
Now, I want the below output:
Employee
Id firstname lastname
1 Rajnikant Patel
2 Steve Jobs
3 Sachin Tendulkar
4 Ratan Tata
Skill
Id title description
1 java java
2 mongodb mongodb
3 PHP PHP
4 spring Spring framework
Employee_skills
Id employee_id skill_id
1 1 1
2 1 2
3 2 1
4 3 2
So I want the query which can return the employee records who have the skills that are passed:
Let's say, I pass in where clause : s.title in ('mongodb', 'java'), then it should return record:
Id firstName lastName
1 Rajnikant Patel
Because this employee has both the skills.

Here is how to do it: Select all employee skills for the desired skills, then only keep employees having the full count.
select *
from employee
where id in
(
select employee_id
from employee_skills
where skill_id in
(
select id
from skill
where title in ('java', 'mongodb')
)
group by employee_id
having count(distinct skill_id) = 2
);
When adding another skill, you must check for a count of 3, of course, etc.

Below query will give you desired results.
SELECT e.id, e.firstname, e.lastname
FROM Employee e
JOIN Employee_skills es
ON es.employee_id = e.id
JOIN Skill s
ON es.skill_id = s.id
WHERE s.title IN ('mongodb', 'java')
GROUP BY e.id
HAVING count(s.id) = 2

Related

SQL: Display results from two tables

I have two tables:
Jobs
job_title min_salary job_id max_salary
Public Accountant 4322 1 8777
Assistant 4321 2 9877
President 5432 3 6766
Employees
emp_id first_name last_name job_id hire_date
100 Abc Def 1 2020-12-09
101 Xyz Efg 2 2020-10-05
102 Hjk Lmn 3 2019-09-06
job_id is common in both tables. I want to display the first and last name and date of joining of the employees who are either Assistant or President...
I am trying to get the output using this:
SELECT first_name
, last_name
, hire_date
FROM employees
UNION
( SELECT job_title
FROM jobs
WHERE job_title = 'Assistant'
or job_title = 'President');
But I am doing something wrong when selecting the required columns...
Thanks
You should to use JOIN:
SELECT first_name, last_name, hire_date
FROM Employees
JOIN Jobs ON Employees.job_id = Jobs.job_id
WHERE job_title IN ('Assistant', 'President');
Here live SQL fiddle
You need to change the query like this:
SELECT *
FROM tutorial.crunchbase_investments_part1
UNION
SELECT *
FROM tutorial.crunchbase_investments_part2
Source

How do I join two tables in SQL to grab the names from one table and show them in a query?

I have two tables like this:
Employee Table:
EmployeeID
firstName
lastName
1
Johnny
Depp
2
Rebecca
Smith
3
Rodger
Doe
Sales Table:
EmployeeID
Sales
1
100.20
2
200.19
3
355.23
And I'd like to join the tables to do something like this:
EmployeeID
fullName
Sales
1
Johnny Depp
100.20
2
Rebecca Smith
200.19
3
Rodger Doe
355.23
How would I do that? Here's what I tried so far:
SELECT employee.firstName + employee.lastName AS fullName, employeeID, sales
FROM employee i
INNER JOIN Sales s ON s.customerID = i.CustomerID
I'm getting a syntax error at my "+" symbol.
What's my problem?
as #Gordon said ,use CONCAT():
SELECT CONCAT(employee.firstName, ' ', employee.lastName) AS fullName
, employeeID
, sales
FROM employee i
INNER JOIN Sales s
ON s.customerID = i.CustomerID

How can I filter the information excluding some of the values in SQL?

I have the following tables:
create table Person (
id_person int,
name varchar(255),
primary key (id_person)
);
create table Journey (
id_journey int,
year int,
country varchar(255),
primary key (id_journey),
);
create table Person_Journey (
id_journey int references Journey (id_journey),
id_person int references Person (id_person),
primary key (id_journey, id_travel)
);
Imagine the data inserted into this tables are:
Table Person
id_person name
-----------------------------------------------
1 Jake
2 Kevin
3 Denis
Table Journey (and table Person_Journey):
id_person id_travel country
---------------------------------------------------
1 1 France
1 2 Germany
1 3 Portugal
2 4 UK
2 5 Germany
2 6 UK
3 7 UK
3 8 Portugal
3 9 Germany
As the previous example shows, person with id_person = 1 has travelled to Portugal, Germany and France. Person with id_person = 2 has travelled to the UK two times and to Germany. Finally, person with id_person = 3 has travelled to UK, Germany and Portugal.
I have to execute a SELECT on where I want to show the id_person and it's respective name from ONLY the persons that has travelled to the UK AND Germany.
So the output I want to get is:
id_person name
------------------------------
2 Kevin
I have tried executing this with no success:
select P.* from Person as P, Journey as J, Person_Journey as PJ
where P.id_person = PJ.id_person and J.id_journey = PJ.id_journey
and J.country in ("UK", "Germany")
group by (P.id_person)
having count(J.country) = 2;
How can I do this? I'm using MySQL
Try this:
SELECT Person.* FROM Person_Journey
INNER JOIN (
SELECT id_journey FROM Journey
WHERE
country in('Germany', 'UK')
GROUP BY id_journey
HAVING COUNT(DISTINCT country) = 2
) t
ON Person_Journey.id_journey = t.id_journey
INNER JOIN Person ON Person.id_person = Person_Journey.id_person
Well, one solution without joins could be with IN's:
SELECT * FROM Person
WHERE id_person IN (
SELECT id_person FROM Person_Journey
WHERE id_journey IN(
SELECT id_journey FROM Journey
WHERE
country in('Germany', 'UK')
GROUP BY id_journey
HAVING COUNT(DISTINCT country) = 2
)
)
Though, say in university, that joins are still better, than this ))
I would use EXISTS:
Pseudo code:
Select person names where their ID appear in a row "Germany" and in a row "UK" of the Journey table.
Which would translate to:
SELECT p.name FROM Person p
WHERE EXISTS (
SELECT 1 FROM Journey j
WHERE country='UK'
AND p.id_person = j.id_person
AND EXISTS (
SELECT 1 FROM Journey j
WHERE country='Germany'
AND p.id_person = j.id_person
)

Selecting dynamic column in oracle

Table userdetail
Username Department
user1 dept2
user2 dept3
user3 dept4
Table department
dept1 dept2 dept4 dept3 amount region city
hello bye tc tata 500 pakistan lahore
Now If I select "user1" output should be like that
dept2 dept4 dept3 amount region city
bye tc tata 500 pakistan lahore
Now If I select "user3" output should be like that
dept4 amount region city
tc 500 pakistan lahore
Your design is not realy relational..
Typically a DEPARTNEMT table consist of department id (primary key) and ather attributes.
Also a Query returns always the same number of columns, so it is not possible to return once six columns and four columns for ather value.
Anyway, if the department table has only one row, you may do something like this
select u.Username,
decode(u.Department,'dept2',d.dept2,'dept3',d.dept3, 'dept4',d.dept4) dept,
decode(u.Department,'dept2',d.amount,'dept3',d.amount, 'dept4',d.amount) amount
from userdetail u
cross join department d
where u.Username = 'user1'
USERNAME DEPT AMOUNT
-------- ---- ----------
user1 bye 500
Add other columns based on this schema, if required.
select a.username, b.Department, b.amount, b.region, b.city
from userdetail a inner join
(
select 'dept1' as Department, dept1 as dept, amount, region, city
from department
union all
select 'dept2' as Department2,dept2 as dept2, amount, region, city
from department
union all
select 'dept3' as Department3,dept3 as dept3, amount, region, city
from department
union all
select 'dept4' as Department4,dept4 as dept4, amount, region, city
from department
) b on (a.department=b.Department)
where a.username= 'user1';

SQL: Joining to two tables and then using sum() and count()

If I have two tables:
school:
school_id | class_id | school_location
-------------------------------------------
400 50 Arizona
staff:
staff_id | forename | school_id | wage
------------------------------------------
1 Peter 400 5000
How could I get the output the number of staff that work in school and the salary of each school.
For example:
school_id | numberofstaff | salary
---------------------------------------
400 | 1 | 5000
I know I should join the tables like so:
SELECT school_id
FROM school
INNER JOIN staff
ON school.school_id = staff.school_id
However I am unsure how to do the remaining part of the query.
SELECT numberofstaff COUNT(numberofstaff) from staff
GROUP BY school_id
Union all
select 'SUM' numberofstaff, COUNT(numberofstaff)
FROM staff
This should give me my school ids with the number of staff belonging to each school_id.
Once you join both tables, you can then count the staff and sum all the wages for each school:
SELECT sc.school_id,
COUNT(*) as numberofstaff,
SUM(st.wage) as salary
FROM school sc
INNER JOIN staff st
ON sc.school_id = st.school_id
GROUP BY sc.school_id
try this way
SELECT COUNT(staff.numberofstaff) as numberofstaff , school.school_id as school_id FROM school
INNER JOIN staff
ON school.school_id = staff.school_id
GROUP BY school.school_id;