SQL: Display results from two tables - mysql

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

Related

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

Insert into table if second table has conditional value

I have two tables:
Table 1 (customers)
customer_id customer_name salesPerson_id
1 John 1
2 Ed 1
3 Sam 2
Table 2 (customerContacts)
contact_id customer_id phone_number
1 1 687-5309
2 1 555-1234
3 1 742-1111
I am trying to let only the sales person add / update a phone number for their specific customer.
So only sales salesPerson_id 1 could update John and Ed and only salesPerson_id 2 could update Sam.
I believe I am looking for something like:
INSERT INTO customerContacts (contact_id , customer_id , phone_number) VALUES (1 , 1 , '987-6543')
ON DUPLICATE KEY UPDATE phone_number='987-6543'
IF customers.salesPerson_ID = 1
But it doesn't seem like sql supports if statements.
INSERT INTO customerContacts (contact_id , customer_id , phone_number)
Select 1 , customer_id , '987-6543'
from customers
where salesPerson_ID = 1 and customer_id=1;
This is the query which you should use in the native way but you need to fit this in your application framework

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';

Need a query for many to many relationship in 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

SELECT Only Records With Duplicate (Column A || Column B) But Different (Column C) Values

I apologize for the confusing title, I can't figure out the proper wording for this question. Instead, I'll just give you the background info and the goal:
This is in a table where a person may or may not have multiple rows of data, and those rows may contain the same value for the activity_id, or may not. Each row has an auto-incremented ID. The people do not have a unique identifier attached to their names, so we can only use first_name/last_name to identify a person.
I need to be able to find the people that have multiple rows in this table, but only the ones who have multiple rows that contain more than one different activity_id.
Here's a sample of the data we're looking through:
unique_id | first_name | last_name | activity_id
---------------------------------------------------------------
1 | ted | stevens | 544
2 | ted | stevens | 544
3 | ted | stevens | 545
4 | ted | stevens | 546
5 | rachel | jameson | 633
6 | jennifer | tyler | 644
7 | jennifer | tyler | 655
8 | jennifer | tyler | 655
9 | jack | fillion | 544
10 | mallory | taylor | 633
11 | mallory | taylor | 633
From that small sample, here are the records I would want returned:
unique_id | first_name | last_name | activity_id
---------------------------------------------------------------
dontcare | ted | stevens | 544
dontcare | jennifer | tyler | 655
Note that which value of unique_id gets returned is irrelvant, as long as it's one of the unique_ids belonging to that person, and as long as only one record is returned for that person.
Can anyone figure out how to write a query like this? I don't care what version of SQL you use, I can probably translate it into Oracle if it's somehow different.
I would do:
SELECT first_name, last_name, COUNT(DISTINCT activity_id)
FROM <table_name>
GROUP BY first_name, last_name
HAVING COUNT(DISTINCT activity_id) > 0;
I'll build through the logic with you. First, lets find all people that have more than one entry:
Unique list of name + activity ID:
select first_name, last_name,activity_id, count(1)
from yourtable
group by first_name, last_name,activity_id
Now we'll turn that into a subquery and look for users with more than 1 activity_ID
Select first_name, last_name
from
(select first_name, last_name,activity_id, count(1)
from yourtable
group by first_name, last_name,activity_id) a
group by first_name, last_name
having count(1) > 1
Should work as that...I didn't return an activity_id, adding max(activity_id) to the select statement will grab the highest one.
Note that which value of unique_id gets returned is irrelvant, as long as it's one of the unique_ids belonging to that person, and as long as only one record is returned for that person.
These querys should do the trick. there is no need for distinct keywords or an subquery to fetch the results BumbleShrimp needs (if BumbleShrimp needed the correct unique_id also an subquery is needed to match the right value)
Below is the most simple query i could think off that should work, but it could be slow on large tables.
SELECT
first_name
, last_name
, activity_id
FROM
person
GROUP BY
first_name
, last_name
, activity_id
HAVING COUNT(*) >= 2
Could be slow because explain shows "Using index; Using temporary; Using filesort".
Using temporary could trigger an disk based temporary table so we make use off an inner self join to remove the need of an Using temporary.
SELECT
person1.first_name
, person1.last_name
, person1.activity_id
FROM
person person1
INNER JOIN
person person2
ON
person1.unique_id < person2.unique_id
AND
person1.first_name = person2.first_name
AND
person1.last_name = person2.last_name
AND
person1.activity_id = person2.activity_id
ORDER BY
activity_id asc
See demo http://sqlfiddle.com/#!2/fe3ba/29
Side note the inner join will fail if there are three or more duplicates
see demo http://sqlfiddle.com/#!2/1ff33/15
New query
SELECT
first_name
, last_name
, activity_id
FROM
person
GROUP BY
activity_id
, last_name
, first_name
HAVING COUNT(activity_id) >= 2
ORDER BY
activity_id asc
see demo http://sqlfiddle.com/#!2/1e418/3 fixes the three or more duplicates problem / orders activity_id right and can be used on large tables because there is not need off a temporary table what can slow down the execution
To get only the names, the simplest is:
SELECT
first_name
, last_name
FROM
person
GROUP BY
first_name
, last_name
HAVING
COUNT(DISTINCT activity_id) >= 2 ;
To get one row for every name, you can use window function (work fine in Oracle):
WITH cte AS
( SELECT
unique_id, first_name, last_name, activity_id
, COUNT(DISTINCT activity_id) OVER (PARTITION BY last_name, first_name)
AS cnt
, MIN(unique_id) OVER (PARTITION BY last_name, first_name)
AS min_id
FROM
person
)
SELECT
unique_id, first_name, last_name, activity_id
FROM
cte
WHERE
cnt >= 2
AND
min_id = unique_id ;
Instead of MIN(unique_id) OVER ..., you could use MIN(activity_id) OVER ... (or MAX()) and accordingly min_id = activity_id. Or ROW_NUMBER() function. Since you need the COUNT(DISTINCT activity_id) anyway, let me add this version.
With an index on (last_name, first_name, activity_id, unique_id) it should be quite efficient:
WITH cte AS
( SELECT
unique_id, first_name, last_name, activity_id
, COUNT(DISTINCT activity_id) OVER (PARTITION BY last_name, first_name)
AS cnt
, ROW_NUMBER() OVER (PARTITION BY last_name, first_name
ORDER BY activity_id, unique_id)
AS rown
FROM
person
)
SELECT
unique_id, first_name, last_name, activity_id
FROM
cte
WHERE
cnt >= 2
AND
rown = 1 ;
Tested at SQL-Fiddle