SELECT maximum and minimum value from a table - sql

I am trying to get the fname and lname of the person that makes the most money and the person that makes the least.
I am looking for a solution that uses only one query
Select fname, lname
from Employees
where Salary =51,000
and Salary =$28,000;
I tried to figure this out but I could not.
It is using subqueries and I am having a really hard time figuring it out. It is said to use only 1 query.

select fname, lname, Salary
from Employees
where Salary = (select min(Salary) from Employees) or
Salary = (select max(Salary) from Employees)
EDIT: if you know the values of the top/bottom salary, use this:
Select fname, lname
from Employees
where Salary =51,000
OR
Salary =$28,000;
Emphasis on OR.

Related

salary of each employee along with the average salary of department in sql

SELECT
job_id, emp_name, salary, AVG(SALARY) AS AVERAGE_SALARY
FROM
employees
GROUP BY
emp_name, department_id;
I've tried this but this doesn't seem to work.
table: https://i.stack.imgur.com/3jB6x.png
output
: https://i.stack.imgur.com/q7R5T.png
my output: https://i.stack.imgur.com/EfxcZ.png
You seem to want a window average:
select
job_id, emp_name, salary,
avg(salary) over(partition by department_id) as avg_dpt_salary
from employees
This gives you one row per employee, along with the average salary of all employees of the same department.
You're not grouping by salary, yet you want the average. In this case the non-averaged salary column will return a value from a single record if it even works at all.
There's a couple ways to interpret what you're asking for.
Perhaps you want a report of each employee, but you want the average for the entire department. I believe you're grouping by emp_name because you want each employee's name in the output. You could do that this way in MariaDB:
select
job_id, emp_name, salary, (
select avg(salary) from employees b where b.department_id = a.department_id
) as avg_salary
from
employees a;
The other way to interpret what you're asking is if the same employee has multiple entries in the database and you only want one entry per employee name. The problem there, is what value are you expecting for the non-averaged salary? I've excluded that in the next example since it doesn't make sense to me.
select
emp_name, department_id, avg(salary) as avg_salary
from
employees a;
group by
emp_name, department_id;
I'm not certain either of these actually generate the data you're looking for, so please give me feedback on which of these is closer to what you're looking for and I'll edit the answer if necessary.

Cannot get results to show when querying salary of department based on average salary of department and twice minimum salary of entire company

I am attempting to display the department and average salary of employees in said department if it meets a condition: average salary of department must be twice the minimum salary of the entire firm.
select dname, avg(salary) from department, employee where dno=dnumber group by dname having avg(salary) > min(salary)*2;
I have tables for employee, department. My query is below, however it results in an empty table.
I believe it is because salary in the halving clause is referencing within department and within employee - or rather it isn't doing this properly.
To just list average salaries by department I used this query which seems to work fine:
select dname, avg(salary) from department, employee where dno=dnumber group by dname;
Any help would be much appreciated.
Thank you!
min(salary) is the minimum of the department, replace it with (select min(salary) from employee)

Oracle SQL sub query

I have a practice that I should find the employees who earn more than average salary and works in the departments with employees whose last name contains the letter u
the select statement I have used was
SELECT employee_id,
last_name,
salary
FROM employees
WHERE salary > (SELECT AVG(salary)
FROM employees )
AND department_id IN(SELECT department_id
FROM employees
WHERE LOWER(last_name) LIKE '%u%')
Could anyone check this statement is suitable or not ?
thank you
That looks fine to me, assuming you mean the average salary across all departments in the database, and all employees (active or not) across all of time.
I would think you might be more interested in all active employees in this current financial year, for example.
You haven't provided the schema, so be careful to check for conditions like:
inactive departments
inactive / terminated employees
period you are interested in for comparing the salary
Your queries looks like it will work. You can rewrite it to remove all the sub-queries (that will require additional table/index scans) and just use analytic queries:
SELECT employee_id,
last_name,
salary
FROM (
SELECT employee_id,
last_name,
salary,
AVG( salary ) OVER () AS avg_salary,
COUNT( CASE WHEN LOWER( last_name ) LIKE '%u%' THEN 1 END )
OVER ( PARTITION BY department_id ) AS num_last_name_with_u
FROM employees
)
WHERE salary > avg_salary
AND num_last_name_with_u > 0;
db<>fiddle
My first Question are you getting the expected result ?
Let me break down your Query
SELECT department_id FROM employees WHERE LOWER(last_name)
Here you are selecting the department so it retrieve the department id, what is the need of selecting department Id when all you need employee_id with last name contains u so change it to employee_id instead of department_id
select avg(salary) over (partition by department_id order by employee_id)
So using partition by you must get the avg salary per department
SELECT employee_id,last_name,salary
FROM
employees
WHERE salary>(SELECT AVG(salary) OVER (PARTITION BY department_id)
FROM
employees )
AND employee_id IN
( SELECT employee_id
FROM
employees
WHERE LOWER(last_name) LIKE '%u%')
Let me know if you have any issues running it, any corrections to Query is appreciated

Unexpected result of a SQL query

Can anyone explain why this query:
SELECT employee_id, last_name, salary
FROM employees
WHERE department_id IN (SELECT department_id
FROM employees
WHERE last_name LIKE '%u%'
)
AND salary > (SELECT AVG(salary)
FROM employees);
returns way less rows than this nested one:
SELECT employee_id, last_name, salary
FROM employees
WHERE department_id IN (SELECT department_id
FROM employees
WHERE last_name LIKE '%u%'
AND salary > (SELECT AVG(salary)
FROM employees);
)
The first returns all employees who meet the following conditions:
The employee is in a department has a "u" employee.
The employee has a salary larger than the average.
The second returns all employees who meet these conditions:
The employee is in a department that has a "u" employee who has a salary larger than the average.
The two are very different conditions. I wouldn't expect them to return the same result set.
Also, whenever you have more than one table in a query, you should use table aliases that are abbreviations of the table name and you should qualify all column names.

Retrieve the names of employees who is making least in their departments

I have two tables
EMPLOYEE (Fname, Lname, Ssn, Salary, Dno)
DEPARTMENT (Dname, Dno, Location)
I want to list the names of all employees making the least in their department
I have come up with this
select min(E.Salary) from EMPLOYEE E group by E.Dno;
but how do I join the EMPLOYEE table with it and display the 'Fname' and 'Lname';
Analytic functions would be best but this would also work:
select *
from employee e
where salary = (select min(x.salary) from employee x where x.dno = e.dno)
Use Analytic function, ROW_NUMBER() OVER( PARTITION BY DNO ORDER BY SALARY) as RN. So, WHERE RN = 1 will give you the employee with least salary in each department.
Remember, if there are two employees with same salary, then you need to use DENSE_RANK to avoid similar rank.
Note : This answer is for Oracle.
A simple way to do it is to check that no one with a lower salary exists in the same department;
SELECT e1.*
FROM employee e1
WHERE NOT EXISTS(
SELECT 1 FROM employee e2 WHERE e1.dno = e2.dno AND e1.salary > e2.salary
);
An SQLfiddle to test with.