How can I switch the name in the row? - mysql

Here's my query:
select project_number, concat(first_name,' ',last_name) as employee_name, department_name
from ex.projects p right join employees e
On e.employee_id = p.employee_id
right join departments d
on d.department_number = e.department_number
order by department_name
How can I switch the two people names? Need "cindy smith' to be on bottom of "Ralph simonian" and "Robert Aaronsen" to be on top "Ralph simonian"

I would do this using left join rather than right join. Reading left join is easier: keep everything in the first table and then matching rows in the rest. This is easier to read than . . . "wait til you see what is in the last table to see what the rows are going to be."
But leaving your method, you need an order by:
select project_number, concat(first_name, ' ', last_name) as employee_name,
department_name
from ex.projects p right join
employees e
On e.employee_id = p.employee_id right join
departments d
on d.department_number = e.department_number
order by department_name, last_name;

based on your sample, you only need to add in the order clause the project number and employee name in descending order
order by department_name, project_number, employee_name desc

Related

SQL: Employee, Manager, City Names

I am super new to SQL, but hoping for some input on the below. In this assignment, we aren't supposed to use PK or FK so everything is cross referenced. I have an EMPLOYEE table with a column for Manager ID as the Employee ID, and a CityID which is referenced to the City table which includes the ID and Name.
I need to pull up the Employee's name, employee's city, manager name and the managers city, the issue I am having is, one the manager has a NULL value in the City, so it is not producing all of the possible results. If there is a NULL value in any of the columns, I want it to show NULL.
Any idea what I could add to allow for NULL values?
Here is the query so far:
SELECT
CONCAT(e.FirstName, ' ', e.LastName) AS 'EmployeeName', c.CityName AS 'EmployeeCity',
CONCAT(m.FirstName, ' ', m.LastName) AS 'ManagerName', ci.CityName AS 'ManagerCity'
FROM
EMPLOYEE e
JOIN
EMPLOYEE m
ON e.ManagerID = m.EmployeeID
JOIN
CITY c
ON e.CityID = c.CityID
JOIN
CITY ci
ON m.CityID = ci.CityID;
JOIN returns all rows from tables where the key record of one table is equal to the key records of another table
INNER JOIN returns only matching tuples/rows if there is a much on the right of he compared tables.
While LEFT OUTER JOIN returns all matching tuples/rows from both compared tables.
I recommend that you use LEFT OUTER JOIN in your case.
In your case, just use concat_ws():
SELECT CONCAT_WS(' ', e.FirstName, e.LastName) AS EmployeeName,
c.CityName AS EmployeeCity,
CONCAT_WS(' ', m.FirstName, m.LastName) AS ManagerName,
ci.CityName AS ManagerCity
CONCAT_WS() ignores NULL values. And as a bonus, won't include the space.
Note: Only use single quotes for string and date constants. Do not use them for column names.
#casscode you need to use a LEFT JOIN in your query, like this:
SELECT CONCAT(e.FirstName, ' ', e.LastName) AS 'EmployeeName',
c.CityName AS 'EmployeeCity',
CONCAT(m.FirstName, ' ', m.LastName) AS 'ManagerName',
ci.CityName AS 'ManagerCity'
FROM EMPLOYEE e
JOIN EMPLOYEE m ON e.ManagerId = m.EmployeeId
LEFT JOIN CITY c ON e.CityId = c.CityId
LEFT JOIN CITY ci ON m.CityId = ci.CityId;

JOIN subquery and different reault

I was writing an exercise about "Write a query to find the names (first_name, last_name) of the employees who are not supervisors"
I write it on my own and when i check the result or both, mine has less rows than the other.
I was using the JOIN function and the other doesn't.
I want help to know why two results are so different.
Thanks
the one i use join
SELECT
first_name, last_name
FROM
employees AS E
JOIN
departments AS D ON E.department_id = D.department_id
WHERE
NOT EXISTS( SELECT
0
FROM
departments
WHERE
E.manager_id = D.manager_id)
order by last_name;
the one doesn't use join
SELECT
b.first_name, b.last_name
FROM
employees b
WHERE
NOT EXISTS( SELECT
0
FROM
employees a
WHERE
a.manager_id = b.employee_id);
The big problem is that the NOT EXISTS subquery is referencing rows from the joined table. The manager_id column is qualified with D., and that's a reference to the joined table, not the table in the FROM clause of the subquery.
E.manager_id = D.manager_id
^^^^^^^ ^
We also suspect that an employee's supervisor is recorded in the employee row, as a reference to another row in the the employee table. But we don't have the schema definition or any example data, so we're just guessing.
It seems like there would be a supervisor_id in the employee table...
SELECT e.first_name
, e.last_name
, e.department_id
, d.department_id
FROM employees e
WHERE NOT EXISTS
( SELECT 1
FROM employees s
WHERE s.id = e.supervisor_id
)
ORDER
BY e.last_name
, e.first_name
It's also possible that some rows in employee have a value in the department_id column that don't have a matching row in the department table. If there is no matching row in department, the inner join will prevent the row from employee from being returned.
We can use an outer join when we want to return rows even when no matching row is found in the joined table. If we want to involve the departments table, because a "supervisor" is defined to be an employee that is the manager of a department, we can employ an anti-join pattern...
SELECT e.first_name
, e.last_name
FROM employees e
LEFT
JOIN departments d
ON d.manager_id = e.employee_id
WHERE d.manager_id IS NULL
ORDER
BY e.last_name
, e.first_name
Again, without a schema and some sample data, we're just guessing.
This query can be written using only Employees table, but in your query you have joined the employees table with department table. A query should be written with the minimal amount of tables that suffice your expected output, joining unnecessary tables may result in wrong out puts.
In this case you are joining Employees with department here what if there is no Department_ID in employee table for some employees, so those data will be dropped in the join and result won't be the expected.

SQL Query Ailas issue

Here's my question. I'm just not even sure where I should start.
List the first name, last name, and title of each employee, as well as the first name, lastname, and title of their supervisor; employees without supervisors should have null for theirsupervisor values. Alias only the columns for the supervisor toSuperFirst,SuperLast,andSuperTitle; columns should be ordered asFirstName,LastName,Title,SuperFirst,SuperLast, andSuperTitle.
Here's the ER Diagram:
What is the question here? Please provide a clear question for us to work with.
Example Below for reference.
LEFT Join return all Employees all results that have a supervisor and ones that don't. The ones that don't would have a NULL value in the "S.*" columns. That should accomplish what you need.
SELECT FirstName, LastName, Title, S.FirstName AS SuperFirst, S.LastName AS SupertLast, S.Title AS SuperTitle
FROM dbo.Employee E
LEFT JOIN dbo.Employee S ON E.ReportsTo = S.EmployeeID
You are looking for a self-join on Employee Table as below as it references itself.
SELECT emp.FirstName
,emp.LastName
,emp.Title
,super.FirstName as SuperFirst
,super.LastName as SuperLast
,super.Title as SuperTitle
FROM employee emp
LEFT JOIN employee super ON emp.reportsto = super.EmployeeId
ORDER BY 1
,2
,3
,4
,5
,6;
Left join will put null in Supervisor columns if no matching values are retrieved.
Like mentioned before, when LEFT JOIN you should be able get NULL when there is no match. This code should work!
SELECT Employee.FirstName, Employee.LastName, Employee.Title, Emp.FirstName AS SuperFirst, Emp.LastName AS SuperLast, Emp.Title AS SupperTitle
FROM Employee LEFT JOIN Employee AS Emp ON Employee.ReportsTo = EmployeeTwo.EmployeeId

Mysql query using IN with group_concat result

I'm trying to clean a db with duplicate records. I need to move the reference to a single record and delete the other one.
I have two tables: Promoters and Venues, each has a reference to a table called cities. The problem is that there are cities with the same name and different ids, that have a relation with venues and promoters.
With this query I can group all promoters and venues with a single city record:
SELECT c.id as id, c.name as name, GROUP_CONCAT( DISTINCT p.id ) as promoters_ids, GROUP_CONCAT( DISTINCT v.id ) as venues_ids
FROM cities as c
LEFT JOIN promoters as p ON p.city_id = c.id
LEFT JOIN venues as v ON v.city_id = c.id
WHERE c.name IN ( SELECT name from cities group by name having count(cities.name) > 1 )
GROUP BY c.name
Now I want to run an UPDATE query on promoters, setting the city_id equals to the result of the query above.
Something like this:
UPDATE promoters AS pr SET pr.city_id = (
SELECT ID
FROM (
SELECT c.id as id, c.name as name, GROUP_CONCAT( DISTINCT p.id ) as promoters_ids
FROM cities as c
LEFT JOIN promoters as p ON p.city_id = c.id
WHERE c.name IN ( SELECT name from cities group by name having count(cities.name) > 1 ) AND pr.id IN promoters_ids
GROUP BY c.name
) AS T1
)
How can I do this?
Thanks
If I understand correctly, you want to remove duplicate cities (in the end), so you need to update promoters that are linked to any of the cities you want to remove in that process.
I think it makes sense to use the lowest ID of any of the cities with the same name (could be the highest just as well, but I want to specify it at least, and don't leave it up to me.
So in order get the right ID for a promoter, I need to: Select the lowest ID of all cities that have the same name as the city already linked to a promoter.
Fortunately, that demand fits snuggly into a query:
UPDATE promoters AS pr
SET pr.city_id = (
SELECT
-- Select the lowest ID ..
Min(c.id)
FROM
-- .. of all cities ..
Cities c
-- .. that have the same name ..
INNER JOIN Cities pc on pc.Name = c.Name
WHERE
.. as the city already linked to the promoter being updated
pc.id = pr.city_id
GROUP BY
c.name)
The trick is to join Cities on itself by name, so you can easily get all cities with the same name. I think you tried the same with the IN clause, but that's a little more complex than it needs to be.
I don't think you need group_concat at all, besides checking if the inned query returns the correct cities indeed, although it doesn't make sense, since you're already grouping on the name. When written like this, you can tell that there should be no way that this can go wrong:
SELECT
-- Select the lowest ID ..
MIN(c.id) AS id,
GROUP_CONCAT(c.name) AS names --< already grouped by this, so why...
FROM
-- .. of all cities ..
Cities c
-- .. that have the same name.
INNER JOIN Cities pc on pc.Name = c.Name
GROUP BY
c.name
I hope I understood the question correctly.

Joining tables using foreign key

I have 2 tables , employees and departments.
departments(id, department)
employees(id, department_id, name, and a bunch more here)
so employees.department_id is a foreign key to departments.id.
I need to show the table employees, but instead of department_id (showing the IDs of the departments) I need to show the actual departments name, so in place of department_id, i need to place departments.department.
How should I do this?
Your friend told you the truth :p
You just have to use a inner join between your two tables like this:
SELECT d.name, e.name, e.email, ... FROM deparments d INNER JOIN employees e ON d.id = e.department_id.
You have to adapt your field to have the desired output :)
SELECT employees.id, employees.department_id, employees.name, departments.department
FROM employees
INNER JOIN departments ON employees.department_id = departments.id
You should not use SELECT * and just take the fields you really want if it's only to take a screenshot of the table values.
Like SELECT department.name
This should cover it for you:
SELECT
E.Id
, D.Department
, E.Name
-- More stuff
FROM Employees E
INNER JOIN Departments D
ON D.id = E.department_id
SELECT employees.*, department.department
FROM employees
INNER JOIN department ON employees.department_id = department.id