Query to sum the previous values - sql

I have the table strucure as in the image.
I need to get the values added to the sum of previous values(shown in the REQUIRED RESULT)
I tried with the following query
SELECT empid,
sum(tot_hours) OVER (PARTITION BY empid ORDER BY empid ) AS tot_hours
FROM empDet
ORDER BY empid
But i get the following result set
But I need the result as in the first picture.
Can anyone help me doing this?

sum(tot_hours) OVER (PARTITION BY empid ORDER BY empid ) AS tot_hours
Your ORDER BY is incorrect. If you want the running SUM on the TOT_HOURS, then you should order by tot_hours.
For example, the below query will calculate the running sum of salary of employees in each department:
SQL> SELECT deptno,
2 sal,
3 SUM(sal) OVER (PARTITION BY deptno ORDER BY sal ) AS tot_sal
4 FROM emp
5 ORDER BY deptno;
DEPTNO SAL TOT_SAL
---------- ---------- ----------
10 1300 1300
10 2450 3750
10 5000 8750
20 800 800
20 1100 1900
20 2975 4875
20 3000 10875
20 3000 10875
30 950 950
30 1250 3450
30 1250 3450
30 1500 4950
30 1600 6550
30 2850 9400
14 rows selected.
SQL>
Update For duplicate values, the running total would be duplicate. To make it unique, use UNBOUNDED PRECEDING clause. For example,
SQL> SELECT empno, deptno,
2 sal,
3 SUM(sal) OVER (PARTITION BY deptno ORDER BY sal ROWS UNBOUNDED PRECEDING) AS tot_sal
4 FROM emp
5 ORDER BY deptno;
EMPNO DEPTNO SAL TOT_SAL
---------- ---------- ---------- ----------
7934 10 1300 1300
10 1300 2600
7782 10 2450 5050
7839 10 5000 10050
7369 20 800 800
7876 20 1100 1900
7566 20 2975 4875
7788 20 3000 7875
7902 20 3000 10875
7900 30 950 950
7521 30 1250 2200
7654 30 1250 3450
7844 30 1500 4950
7499 30 1600 6550
7698 30 2850 9400
15 rows selected.
SQL>

Related

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>

how to query a table using name from another column from another table

I am trying to get data from a table where the table name is stored in another table.
I am trying for select query but not able to get the data.
example
t1
table name | some data
t2 - table name is same coming from t1
t2
id | some data
I need to fetch the t2 name first from t1 that I am able to do. but using that query response I am not sure how to fetch the second query as the result is coming from first query.
Any help is appreciated.
Thanks
It'll have to be some kind of "dynamic" SQL. One option is to create a function that returns ref cursor. Here's an example.
This is your t1 table; it contains some table names.
SQL> select * from tname;
ID TABLE_NAME
---------- ---------------
1 emp
2 dept
Function:
SQL> create or replace function f_tab (par_table_name in varchar2)
2 return sys_refcursor
3 is
4 rc sys_refcursor;
5 begin
6 open rc for 'select * from ' || dbms_assert.sql_object_name(par_table_name);
7 return rc;
8 end;
9 /
Function created.
Testing: query selects table names from the tname table and returns their contents:
SQL> select f_tab(t.table_name) result
2 from tname t
3 order by t.id;
RESULT
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17.12.1980 00:00:00 800 20
7499 ALLEN SALESMAN 7698 20.02.1981 00:00:00 1600 300 30
7521 WARD SALESMAN 7698 22.02.1981 00:00:00 1250 500 30
7566 JONES MANAGER 7839 02.04.1981 00:00:00 2975 20
7654 MARTIN SALESMAN 7698 28.09.1981 00:00:00 1250 1400 30
7698 BLAKE MANAGER 7839 01.05.1981 00:00:00 2850 30
7782 CLARK MANAGER 7839 09.06.1981 00:00:00 2450 10
7788 SCOTT ANALYST 7566 09.12.1982 00:00:00 3000 20
7839 KING PRESIDENT 17.11.1981 00:00:00 5000 10
7844 TURNER SALESMAN 7698 08.09.1981 00:00:00 1500 0 30
7876 ADAMS CLERK 7788 12.01.1983 00:00:00 1100 20
7900 JAMES CLERK 7698 03.12.1981 00:00:00 950 30
7902 FORD ANALYST 7566 03.12.1981 00:00:00 3000 20
7934 MILLER CLERK 7782 23.01.1982 00:00:00 1300 10
14 rows selected.
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>

How to select middle 80% rows in Oracle SQL with order by (top % is not working)

I tried top % but that is not working in Oracle SQL. Offset and fetch next are working but I am not able to give percentage.
What will be the best way to fetch middle 80% rows?
Any help will be appreciated, thanks!
Middle 80%? That's between 10 and 90%, then? Let's suppose it is.
Sample data (Scott's EMP table), sorted by salary:
SQL> select ename, job, sal,
2 rank() over (order by sal) rnk
3 from emp order by sal;
ENAME JOB SAL RNK
---------- --------- ---------- ----------
SMITH CLERK 800 1
JAMES CLERK 950 2
ADAMS CLERK 1100 3
WARD SALESMAN 1250 4
MARTIN SALESMAN 1250 4
MILLER CLERK 1300 6
TURNER SALESMAN 1500 7
ALLEN SALESMAN 1600 8
CLARK MANAGER 2450 9
BLAKE MANAGER 2850 10
JONES MANAGER 2975 11
SCOTT ANALYST 3000 12
FORD ANALYST 3000 12
KING PRESIDENT 5000 14
14 rows selected.
CTE ranks employees by their salaries; the final where clause returns rows for those of them who fall into that "middle" 80% (the pct column).
SQL> with temp as
2 (select ename, job, sal,
3 rank() over (order by sal) rnk, -- rank rows by salary
4 count(*) over (order by null) cnt -- total number of rows
5 from emp
6 )
7 select t.*,
8 round(rnk / cnt * 100) pct -- percentage
9 from temp t
10 where round(rnk / cnt * 100) between 10 and 90;
ENAME JOB SAL RNK CNT PCT
---------- --------- ---------- ---------- ---------- ----------
JAMES CLERK 950 2 14 14
ADAMS CLERK 1100 3 14 21
WARD SALESMAN 1250 4 14 29
MARTIN SALESMAN 1250 4 14 29
MILLER CLERK 1300 6 14 43
TURNER SALESMAN 1500 7 14 50
ALLEN SALESMAN 1600 8 14 57
CLARK MANAGER 2450 9 14 64
BLAKE MANAGER 2850 10 14 71
JONES MANAGER 2975 11 14 79
SCOTT ANALYST 3000 12 14 86
FORD ANALYST 3000 12 14 86
12 rows selected.
SQL>

oracle sum by column without using union

I have this table: (supply table: how many products in storages)
Storage_id product_id amount
1 1000 55
1 1005 1
...
29 1000 3
29 1421 21
29 1566 0
30 1259 921
I should write a query to have this result:
storage_id product_id amount
1 1000 55
2 1000 61
...
30 1000 10
total_except_storage_30 1000 1505
1 1001 1
2 1001 50
...
30 1001 56
total_except_storage_30 1001 1251
...
"Total_except_storage_30" has the total of every product in storages except storage number 30. For example first "total_except_storage_30" is for product_id 1000 in all storages except storage_id 30 and the second is for product_id 1001.
*** I am not allowed to use "Union".
I tried to use full outer join but this did not work and the result is without "total_except_storage_30":
Select t.Storage_id, t.product_id, t.amount
from myTable t full outer join
(
select 'total_except_storage_30' as storage_id, product_id, sum(amount)
from myTable
group by product_id
) total
on t.storage_id = total.storage_id
Something like this should do it
select
product,
storage_id,
sum(case when storage_id != 30 then sal end)
from scott.emp
group by grouping sets (
(storage_id,product),
(product)
)
order by product, storage_id;
Here's an example of that using the standard EMP, DEPT
SQL> select
2 deptno,
3 empno,
4 sum(sal)
5 from scott.emp
6 group by grouping sets (
7 (empno,deptno),
8 (deptno)
9 )
10 order by deptno, empno;
DEPTNO EMPNO SUM(SAL)
---------- ---------- ----------
10 7782 2450
10 7839 5000
10 7934 1300
10 8750
20 7369 800
20 7566 2975
20 7788 3000
20 7876 1100
20 7902 3000
20 10875
30 7499 1600
30 7521 1250
30 7654 1250
30 7698 2850
30 7844 1500
30 7900 950
30 9400
17 rows selected.
You can see you get subtotals throughout

delete all employees who are working with employee(employee name given by user)

Delete all the who are working with that employee, except that Employee.(Prompt for the ENAME).
the employees will have same department number.can anyone help me out.
delete from emptest e where e.deptno IN
(select f.deptno from emptest f where e.deptno=f.deptno AND
e.empno<>f.empno AND f.ename='&ename' );
Sample data:
SQL> set ver off
SQL> undefine par_ename
SQL> select * from employee order by deptno, ename;
DEPTNO ENAME JOB SAL
---------- ---------- --------- ----------
10 CLARK MANAGER 2450 --> department 10: if KING is a parameter,
10 KING PRESIDENT 5001 --> then CLARK and MILLER will be
10 MILLER CLERK 1300 --> deleted, but KING won't
20 ADAMS CLERK 1100
20 FORD ANALYST 3000
20 JONES MANAGER 2975
20 SCOTT ANALYST 3000
20 SMITH CLERK 1000
30 ALLEN SALESMAN 1600
30 BLAKE MANAGER 2850
30 JAMES CLERK 950
30 MARTIN SALESMAN 1250
30 TURNER SALESMAN 1500
30 WARD SALESMAN 1250
14 rows selected.
Query:
SQL> delete from employee e
2 where e.deptno = (select a.deptno
3 from employee a
4 where a.ename = '&&par_ename'
5 )
6 and e.ename <> '&&par_ename';
Enter value for par_ename: KING
2 rows deleted.
Result:
SQL> select * from employee order by deptno, ename;
DEPTNO ENAME JOB SAL
---------- ---------- --------- ----------
10 KING PRESIDENT 5001 --> only KING remains in dept. 10
20 ADAMS CLERK 1100
20 FORD ANALYST 3000
20 JONES MANAGER 2975
20 SCOTT ANALYST 3000
20 SMITH CLERK 1000
30 ALLEN SALESMAN 1600
30 BLAKE MANAGER 2850
30 JAMES CLERK 950
30 MARTIN SALESMAN 1250
30 TURNER SALESMAN 1500
30 WARD SALESMAN 1250
12 rows selected.
SQL>