What would the query be for the following sample table? - sql

Can you please help me with a query that would display a table like this:
Dept_ID Dept_Name
10 Admin
10 Whalen
20 Sales
20 James
20 King
20 Smith
40 Marketing
40 Neena
and so on...The Schema is HR
Display the Department Id and the Department Name and then the subsequent employees last names working under that department

SELECT Dept_ID, Dept_Name
FROM Your_Table
Simple as I can make it. It's very difficult (near impossible) to tell exactly what the query should be without more detail in terms of your table structure and some sample data.
From your edit, you may need something more like this;
SELECT DT.Dept_ID, DT.Dept_Name, ET.Emp_Name
FROM Dept_Table AS DT INNER JOIN Emp_Table AS ET ON DT.Dept_ID = ET.Dept_ID
ORDER BY Dept_ID
This shows the employees in each department on the next column, you don't really want all that in the same column.

When you union two data sets, there is NO implicit ordering, you could get the results in any order.
The get a particular order you must use ORDER BY.
To use ORDER BY, then you must have fields to do that ordering by.
In your case, the pseudo code would be...
- ORDER BY [dept_id], [depts-then-employees], [dept_name]
The middle of those three is something that YOU are going to have to create.
One way of doing that is as follows.
note: Just because you have a field to order by, does not mean that you have to select it.
SELECT
dept_id,
dept_name
FROM
(
SELECT
d.dept_id,
d.dept_name,
0 AS entity_type_ordinal
FROM
department d
UNION ALL
SELECT
d.dept_id,
e.employee_name,
1 AS entity_type_ordinal
FROM
department d
INNER JOIN
employee e
ON e.dept_id = d.dept_id
)
dept_and_emp
ORDER BY
dept_id,
entity_type_ordinal,
dept_name

Assuming there's a table in your database called departments that holds this information, your code might look like this:
select
dept_id, dept_name
from
departments

If you want to display certain columns of the table like you have asked in the question above , you can use the following syntax :
select column_names from table_name
replace:
column_names with the column names you want to display separated by a coma
2.table_name with the name of the table whose columns you wish to display
for the above question , the following code will do:
select Dept_Id , Dept_Name from Department ;
The above code works if your table name is 'Department'

Related

Creating dynamic query which has also has a sub-query

I use two queries in SQL Server, which I would like to combine and create a single query. Tried few options but of not much success.
Query 1
select emp_id, name, age
from employee
where age > 50
Query 2
select dept_id, dept_name
from department
where emp_id = 'COMPANY.ID' + emp_id
The issue in combining the two queries is, though query 1 can return multiple rows, I can't use a subquery to directly use emp_id from query 1 in query 2 since the emp_id in query 2 has a prefix of 'COMPANY.ID.'+emp_id. Any suggestions?
COMPANY.ID is a constant that gets prefixed to emp_id before saving it in department table.
Example employee table
emp_id name age
-----------------------------
123 John 45
345 Susan 34
789 Pat 66
Example department table
emp_id dept_id dept_name
-----------------------------------------------------------------------
COMPANY.ID.123 123 Accounting
COMPANY.ID.345 123 Accounting
Hope these examples help understand my dataset
I understand that you are trying to pull out the departments that have at least one employee older than 50.
One solution would be to use an EXISTS condition with a correlated subquery:
SELECT dept_id, dept_name
FROM department d
WHERE EXISTS (
SELECT 1
FROM employee e
WHERE
CONCAT('COMPANY.ID.', e.emp_id) = d.emp_id
AND e.age > 50
)
Demo on DB Fiddle
Is this what you want as
Query 2 is totally wrong and would never match instead would have used like %CompanyId%
select distinct dept_id, dept_name
from
department where empid IN (
select emp_id from
employee where age > 50 and empid
like '%CompanyId%' )
You can combine the two tables using join
SELECT d.dept_id, d.dept_name
FROM department d
INNER JOIN employee e
ON CONCAT('COMPANY.ID.', e.emp_id) = d.emp_id
WHERE e.age > 50

Count and group by not working as expected

select count(*),manager_id
from departments
group by manager_id;
this is my idea of how to, but it dosent gives me the amount of employees for each manager
I suspect you are selecting from the wrong table, the logic seems correct but the fact that you are selecting from a table call departments is a little suspicious.
Do you have an employee tables? Does it contains a manager_id column? If so:
select count(*),manager_id
from employees
group by manager_id;
If employee tables has only department_id column then :
SELECT d.manager_id,count(*)
FROM employees e
INNER JOIN departments d
ON(e.department_id = d.id)
Using the sample table from the HR schema
select MANAGER_ID, count(*), count(distinct EMPLOYEE_ID)
from HR.EMPLOYEES
group by MANAGER_ID
order by 1 nulls first;
gives
MANAGER_ID COUNT(*) COUNT(DISTINCTEMPLOYEE_ID)
---------- ---------- --------------------------
1 1
100 14 14
101 5 5
102 1 1
Note the first row, with manager IS NULL - i.e. there is a one employee without a manager.
Not also that I use both count(*)and count(distinct EMPLOYEE_ID). This is not relevant for this table, where EMPLOYEE_ID is PK, but in general case the former returns the number of record the latter the number of employees (which can be lower).
I have faced a similar problem of yours.
Try adding inside the count the id that you are counting ie employeeid.
If it still doesnt work after that try adding the same id in the group by.

select column from table with only matched data from another table

I need to select 2 column from table with matched data from another table or cell be null ,
table 1 named "emp" contain emp_name ,emp_id
table 2 named "salary" contain emp_sal, emp_id
I need to create select query
have all emp_name, emp_id and emp_sal (for only the employees will take sale) or be Null
thanks for help now ((((update ))))
first thanks for help
i used
SELECT emp.emp_id,emp.emp_name,salary.emp_sal FROM emp LEFT JOIN salary ON emp.emp_id = salary.emp_id;
it work but with a lot of duplication and i need to make this query with day ...
i create another table named "day" i need query appear day i entered in this table
this table have only one column and i record ((day user entered and saved in "day.user_day"))
i need to link this three tables
together
and lets make it easy we will change salary to attendance ...
i need to query all names and id in date and apear all employee what ever thy have time or not
like when i search only in day 4/8/2014
name id time
john 1 04/08/2014 06:00
man 2 null
scsv 3 04/08/2014 07:00
You want a LEFT JOIN:
SELECT * FROM emp LEFT JOIN salary ON emp.emp_id = salary.emp_id;
This will return all employees along with their emp_sal, which will be NULL if it's not in the salary table.
If what I read is right, you want to get the employee name and salary, returning all employees regardless if they have an entry in salary. If that is correct, this should work:
SELECT
e.emp_name,
e.emp_id,
s.emp_sal
FROM
emp AS e
LEFT JOIN salary AS s ON e.emp_id = s.emp_id
If, however, you only wanted the employees with an entry in the salary table, change LEFT JOIN to be INNER JOIN.

SQL Query using Group by 4

I have tables which looks like below.
Employee table
Date Employee ID Employer ID Salary
2/3/2011 10 20 45666
3/12/2009 43 53 2356
Employer Table
Employer ID State
53 OH
42 MI
Trying to get the total salary by month and by state using group by clause. But not getting the results. what am i doing wrong?? any help appreciated
select date, sum(salary) from employee
group by to_char(date,'MON')
select sum(salary) from employee A, Employer B
where A.employer id=B.employer id
group by B.state
Also i need to get the top 10 distinct employee ids based on their salary
select DISTINCT employee id from employee
where rownum<=10
order by salary desc
You have to group by the exact expression in your select list, e.g.,
select to_char(date,'MON'), sum(salary)
from employee
group by to_char(date,'MON');
You probably want to include the state in your second query:
select b.state, sum(salary)
from employee A, Employer B
where A.employer_id=B.employer_id
group by B.state;
Generally speaking, stating in your question that you're "not getting the results" is not very helpful to the folks you're asking help of. Please provide any error messages or output that describes what "not getting the results" means.

ID value is lost after performing MIN then GROUP BY. Why?

To simplify, if I had a table called 'employee':
id INT NOT NULL PRIMARY KEY,
salary FLOAT,
department VARCHAR(255)
I want to perform and query where I retrieve the minimum salary in each department.
So my query is something like this:
SELECT employee.ID, MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department
But regardless of which records are found. The ID values in the result set are renamed to 1,2,3.... up to however many records (departments) exist in the result set.
How can I maintain the actual ID's of the employees after performing the AGGREGATE function and GROUP BY?
You can't. Think about it, If a Department has 20 employees, and for that department, there are three employees that have the same minimum salary, which EmployeeId do you want the the query output to display? if it was guaranteed that there was only one employee in each dept with that lowest salary, then it can be done by selecting the specific employee records where the salary is the minimum value for each Department:
Select EmployeeID
From Employee e
Where Salary =
(Select Min(Salary) From EMployee
Where DepartmentId = e.DepartmentId)
but this will return multiple records per department when more than one employee has that min salary level.
I would guess you're using MySQL or SQLite, because your query is ambiguous and isn't allowed by standard SQL or most brands of RDBMS. MySQL and SQLite are more permissive, so it's your responsibility to resolve the ambiguity.
Here's my usual fix:
SELECT e1.ID, e1.salary, e1.department
FROM employee e1
LEFT OUTER JOIN employee e2 ON (e1.department = e2.department
AND e1.salary > e2.salary)
WHERE e2.department IS NULL;
Here's another solution that gives the same result:
SELECT e1.ID, e1.salary, e1.department
FROM employee e1
JOIN (SELECT e2.department, MIN(e2.salary) AS min_salary
FROM employee e2 GROUP BY e2.department) d
ON (e1.salary = d.min_salary);
Both of these give multiple rows per department if there are multiple employees in the department with identical minimal salaries. You need to decide how to resolve that case, because it's not clear from your problem description.
Your script is invalid:
SELECT employee.ID, MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department
Instead, look at this:
SELECT MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department
If you need the employee id as well, then you need to use a subquery.
This will do the trick:
SELECT employee.department, MIN(employee.salary), employee.ID
FROM employee
GROUP BY 1
In modern SQL Server releases (and other reasonably powerful and modern SQL engines), SQL "Window functions" are probably the best alternatives (to be preferred over subqueries and self-joins) to do what you desire:
SELECT ID, salary, department
FROM employee
WHERE 1 = ROW_NUMBER() OVER(PARTITION BY department ORDER BY salary ASC)
This works when, if multiple employees have the same (department-minimal) salary, you want just a "random-ish" one of them (you can add criteria to the ORDER BY if you want one picked by some specific criteria); look into RANK, instead of ROW_NUMBER, if you want all.