COUNT is incorrect when grouping? - sql

I am trying to display the employee number of each employee who manages other employees with the number of people he or she manages with the below table called emp.
empno ename job mgr hiredate sal comm deptno
----- ------ ---------- ---------- ---------- ------- ------- ------
7369 Smith Clerk 7902 1980-12-17 800 20
7499 Allen Salesman 7698 1981-02-20 1600 300 30
7521 Ward Salesman 7698 1981-02-22 1250 500 30
7566 Jones Manager 7839 1981-04-02 2975 20
7654 Martin Salesman 7698 1981-09-28 1250 1400 30
7698 Blake Manager 7839 1981-05-01 2850 30
7782 Clark Manager 7839 1981-06-09 2450 10
7788 Scott Analyst 7566 1982-12-09 3000 20
7839 King President 1981-11-17 5000 10
7844 Turner Salesman 7698 1981-09-08 1500 0 30
7876 Adams Clerk 7788 1983-01-12 1100 20
7900 James Clerk 7698 1983-12-03 950 30
7902 Ford Analyst 7566 1983-12-13 3000 20
7934 Miller Clerk 7782 1982-01-23 1300
Any idea of how I can go about doing this?
I have tried
select empno,count(mgr) from emp group by empno,mgr;
but this returns:
empno count(mgr)
---------- ----------
7369 1
7499 1
7521 1
7566 1
7654 1
7698 1
7782 1
7788 1
7839 0
7844 1
7876 1
7900 1
7902 1
7934 1
Thanks so much for your help.

select count(*) from employee_table group by mgr

I would actualy group by mgr, then you'd have a group per manager and can just do a count to see how many persons that manager manages. Then, you could do a self join on the table to get that manager's info. Something like:
SELECT E1.Mgr, E2.ename, Count(*) as Number FROM Employees E1
INNER JOIN Employees E2 ON E1.mgr = E2.empno
GROUP BY E1.Mgr
Though I haven't tested this.

You can try these that do not use join:
select mgr, count(eno)
from employee
group by mgr
or
select name, e1.mgr, count(e1.eno)
from employee e1
group by rollup (e1.mgr, name)

Related

what is query to display only column of target table using left joins

EMP table:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7839 KING PRESIDENT 17-NOV-81 5000 10
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7566 JONES MANAGER 7839 02-APR-81 2975 20
7788 SCOTT ANALYST 7566 19-APR-87 3000 20
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7934 MILLER CLERK 7782 23-JAN-82 1300 10
emp_target table:
TOTAL_NO_OF_EMPLOYEES TOTAL_SAL HIGHEST_SAL LOWEST_SAL AVERGAE_SAL DEPTNO
--------------------- ---------- ----------- ---------- ----------- ----------
6 9400 2850 950 1567 30
5 10875 3000 800 2175 20
3 8750 5000 1300 2917 10
I want to display only:
TOTAL_NO_OF_EMPLOYEES TOTAL_SAL HIGHEST_SAL LOWEST_SAL AVERGAE_SAL DEPTNO
--------------------- ---------- ----------- ---------- ----------- ----------
Output i tried:
Query :
select count(empno) as no_of_employees,sum(sal) as toatl_sal,
max(sal) as highest_Sal,round(avg(sal)) as average_sal, min(sal) as lowest_sal
from emp_target right join emp ON emp_target.deptno = emp_target.deptno ;
Output:
NO_OF_EMPLOYEES TOATL_SAL HIGHEST_SAL AVERAGE_SAL LOWEST_SAL
--------------- ---------- ----------- ----------- ----------
42 87075 5000 2073 800

Get data starting from the middle of the table

I have a question. I want to get data from the middle of the table. But the problem is I can't start from the middle. I have read that rownum can't be used for this. But i dont know how to do this with another method. Anyone have any clue how to do this? Thank you.
Below is an example.
select count(1) --9857
from time_day_dm
where rownum between 5000 and 9857
The output would be 0.
What i expect would be 4857.
rownum won't help here (as you already know).
What you might do, is to use a couple of analytic functions (count, to find number of rows in the table; row_number, to sort them).
Here's an example based on Scott's emp table. This is its contents:
SQL> select empno, ename, job, sal
2 from emp
3 order by ename;
EMPNO ENAME JOB SAL
---------- ---------- --------- ----------
7876 ADAMS CLERK 1100
7499 ALLEN SALESMAN 1600
7698 BLAKE MANAGER 2850
7782 CLARK MANAGER 2450
7902 FORD ANALYST 3000
7900 JAMES CLERK 950
7566 JONES MANAGER 2975
7839 KING PRESIDENT 5000
7654 MARTIN SALESMAN 1250
7934 MILLER CLERK 1300
7788 SCOTT ANALYST 3000
7369 SMITH CLERK 800
7844 TURNER SALESMAN 1500
7521 WARD SALESMAN 1250
14 rows selected.
Query you might be interested in looks like this:
SQL> with temp as
2 (select empno, ename, job, sal,
3 row_number() over (order by ename) rn,
4 count(*) over () cnt
5 from emp
6 )
7 select *
8 from temp
9 where rn between cnt/2 and cnt;
EMPNO ENAME JOB SAL RN CNT
---------- ---------- --------- ---------- ---------- ----------
7566 JONES MANAGER 2975 7 14
7839 KING PRESIDENT 5000 8 14
7654 MARTIN SALESMAN 1250 9 14
7934 MILLER CLERK 1300 10 14
7788 SCOTT ANALYST 3000 11 14
7369 SMITH CLERK 800 12 14
7844 TURNER SALESMAN 1500 13 14
7521 WARD SALESMAN 1250 14 14
8 rows selected.
SQL>

Find the manager details where all the employees under the manager should have salary more than 1000

Im having the table with records like below
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17-DEC-80 800 - 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 - 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 - 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 - 10
7788 SCOTT ANALYST 7566 19-APR-87 3000 - 20
7839 KING PRESIDENT - 17-NOV-81 5000 - 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 - 20
7900 JAMES CLERK 7698 03-DEC-81 950 - 30
7902 FORD ANALYST 7566 03-DEC-81 3000 - 20
7934 MILLER CLERK 7782 23-JAN-82 1300 - 10
and i need to get the manager details where the all the employees under the manager should have salary more than 1000
Here is a solution that uses a correlated subquery:
select e.*
from emp e
where (select min(e1.sal) from emp e1 where e1.mgr = e.empno) >= 1000
This ensures that:
the selected employee is a manager (ie they manage at least one employee)
all of the managees of the manager have a salary above (or equal to) 1000

Why versions_xid value gets reset after some time in Oracle?

While working with row versions query it has been observed the versions_xid value gets removed after some time.
For example:
SQL> select versions_xid, empno, ename, sal from scott.emp
versions between scn minvalue and maxvalue
order by sal;
VERSIONS_XID EMPNO ENAME SAL
---------------- ---------- ---------- ----------
7369 SMITH 800
7900 JAMES 950
7876 ADAMS 1100
7521 WARD 1250
7654 MARTIN 1250
7934 MILLER 1300
7839 KING 1400
7788 SCOTT 1400
7844 TURNER 1500
01002100D6050000 7788 SCOTT 1500
7499 ALLEN 1600
7566 JONES 1800
0800130073070000 7788 SCOTT 1800
06001500DB070000 7788 SCOTT 1900
04000C00B9060000 7788 SCOTT 2000
7782 CLARK 2450
7698 BLAKE 2850
7902 FORD 3000
18 rows selected.
SQL>
After some time when i execute the same query the row versions are gone!
SQL> select versions_xid, empno, ename, sal from scott.emp
versions between scn minvalue and maxvalue
order by sal; 2 3
VERSIONS_XID EMPNO ENAME SAL
---------------- ---------- ---------- ----------
7369 SMITH 800
7900 JAMES 950
7876 ADAMS 1100
7521 WARD 1250
7654 MARTIN 1250
7934 MILLER 1300
7839 KING 1400
7844 TURNER 1500
7499 ALLEN 1600
7566 JONES 1800
7788 SCOTT 2000
7782 CLARK 2450
7698 BLAKE 2850
7902 FORD 3000
14 rows selected.
SQL>
Can someone please let me know whats happening? Is it something to do with undo_retention? Because, reading through various blogs and Oracle docs didn't give a direct answer or relation.

In what order distinct clause with one column(say) displays the output in oracle? [duplicate]

This question already has answers here:
Default row ordering for select query in oracle
(8 answers)
Closed 9 years ago.
EMP table
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 Smith Clerk 7902 12/17/1980 800 30
7499 Allen Salesman 7698 2/20/1981 1600 300 30
7521 Ward Salesman 7698 2/22/1981 1250 500 30
7566 Jones Manager 7839 4/2/1981 2975 20
7654 Martin Salesman 7698 9/28/1981 1250 1400 30
7698 Blake Manager 7839 5/1/1981 2850 30
7782 Clark Manager 7839 6/9/1981 2450 10
7788 Scott Analyst 7566 12/9/1982 3000 20
7839 King President 11/17/1981 5000 10
7844 Turner Salesman 7698 9/8/1981 1500 30
7876 Adams Clerk 7788 1/12/1983 1100 20
7900 James Clerk 7698 12/3/1981 950 30
7902 Ford Analyst 7566 12/3/1981 3000 20
7934 Miller Clerk 7782 1/23/1982 1300 10
Suppose we executed the following query on the above table:
select distinct ename from emp;
Output
ENAME
Ward
Turner
Adams
Allen
Martin
Blake
Clark
Scott
Ford
King
Miller
Jones
Smith
James
Now anyone Please explain me why Ward is displayed as output in the 1st row and not in the order of the table output format??
Because you have to specify an order
select distinct ename
from emp
order by ename
If you don't then the DB will grab the records in the name of performance and output it unordered.
Without ordering how you can expect ordered result.Use order by clause.