Case function with the count condition - sql

I'm using the case function to highlight the current scenario of my task running in my system, where the task status is Completed, Failed or Waiting.
I got the case function to use for Completed and Failed since it was just a one-line command. But for the Waiting state, I would like to build the condition with the count in the case function.
Currently, I'm using the syntax for waiting for the state
CASE WHEN task_Status='Waiting'
and Count(Task_Status) > 30
THEN "More task are in Waiting State"
But the Count Function is giving me ERROR, Requesting the assistance on the same. Thanks in Advance.

It would have been nice if you posted sample data. As you didn't have a look at the following example based on Scott's schema. Instead of your status column, I'm counting clerks in every department.
SQL> select deptno, ename, job from emp order by deptno, job;
DEPTNO ENAME JOB
---------- ---------- ---------
10 MILLER CLERK --> 1 clerk in department 10
10 CLARK MANAGER
10 KING PRESIDENT
20 SCOTT ANALYST
20 FORD ANALYST
20 ADAMS CLERK --> 2 clerks in
20 SMITH CLERK --> department 20
20 JONES MANAGER
30 JAMES CLERK --> 1 clerk in department 30
30 BLAKE MANAGER
30 MARTIN SALESMAN
30 WARD SALESMAN
30 ALLEN SALESMAN
30 TURNER SALESMAN
14 rows selected.
SQL>
This is what you're trying to do now:
SQL> select deptno,
2 case when job = 'CLERK' and count(*) > 1 then
3 'More than a single clerk in department'
4 else
5 'Only one clerk in department'
6 end status
7 from emp
8 group by deptno;
case when job = 'CLERK' and count(*) > 1 then
*
ERROR at line 2:
ORA-00979: not a GROUP BY expression
SQL>
If we include the job column, error goes away, but - result isn't what we expected:
SQL> select deptno,
2 case when job = 'CLERK' and count(*) > 1 then
3 'More than a single clerk in department'
4 else
5 'Only one clerk in department'
6 end status
7 from emp
8 group by deptno, job
9 order by deptno;
DEPTNO STATUS
---------- --------------------------------------
10 Only one clerk in department
10 Only one clerk in department
10 Only one clerk in department
20 Only one clerk in department
20 More than a single clerk in department
20 Only one clerk in department
30 Only one clerk in department
30 Only one clerk in department
30 Only one clerk in department
9 rows selected.
SQL>
What to do? Don't count - sum!
SQL> select
2 deptno,
3 case when sum(case when job = 'CLERK' then 1 else 0 end) > 1 then
4 'More than a single clerk in department'
5 else
6 'Only one clerk in department'
7 end status
8 from emp
9 group by deptno
10 order by deptno;
DEPTNO STATUS
---------- --------------------------------------
10 Only one clerk in department
20 More than a single clerk in department
30 Only one clerk in department
SQL>
In your case, that would be
case when sum(case when task_status = 'Waiting' then 1 else 0 end) > 30 then
'More tasks are in Waiting State'
end
Note that strings should be enclosed into single, not double quotes.

Related

list values ​that are duplicated more than 4 times

I am making a join between 2 tables, where they bring me number_phone that have a relationship and I bring the times that these are repeated, however, I am trying to make a condition to the count, so that it only lists those that are repeated more than 4 times, I tried with having account and it brings me the counter all in null.
It is worth mentioning that I did not occupy group by for the count because it brought me wrong values.
SELECT
REPLACE(REPLACE(t.id_contrato,'0999',''),'0998','')as contrato ,
t.num_telefono,
conc.valor_actual,
(
SELECT COUNT('x')
FROM TBL_TELEFONO ct
WHERE ct.num_telefono = t.num_telefono
AND ct.origen_tel='TELEFONO CONTRATO'
-- HAVING COUNT(*) > 4
) as counter
FROM TBL_TELEFONO t
INNER JOIN CAM_TBL_ALERTA_CONCENTRADO conc ON t.num_telefono = conc.valor_actual
WHERE id_contrato IS NOT NULL
AND id_contrato NOT IN ('N/A')
ORDER BY 4 DESC
How can I list only those that are repeated more than 4 times?
I don't like debugging code with no sample data, so I'll try to illustrate it on Scott's sample EMP table. "Jobs" will act like your "telephone numbers".
SQL> select deptno, ename, job
2 from emp
3 order by job;
DEPTNO ENAME JOB
---------- ---------- ---------
20 SCOTT ANALYST --> 2 analysts
20 FORD ANALYST
10 MILLER CLERK --> 4 clerks
30 JAMES CLERK
20 SMITH CLERK
20 ADAMS CLERK
30 BLAKE MANAGER --> 3 managers
20 JONES MANAGER
10 CLARK MANAGER
10 KING PRESIDENT --> 1 president
30 TURNER SALESMAN --> 4 salesmen
30 MARTIN SALESMAN
30 WARD SALESMAN
30 ALLEN SALESMAN
14 rows selected.
SQL>
According to that, we'd like to fetch all clerks and salesmen as there are 4 (or more) of them.
Instead of count aggregate function, use count in its analytic form:
SQL> select deptno, ename, job,
2 count(*) over (partition by job) cnt
3 from emp
4 order by job;
DEPTNO ENAME JOB CNT
---------- ---------- --------- ----------
20 SCOTT ANALYST 2
20 FORD ANALYST 2
10 MILLER CLERK 4
30 JAMES CLERK 4
20 SMITH CLERK 4
20 ADAMS CLERK 4
30 BLAKE MANAGER 3
20 JONES MANAGER 3
10 CLARK MANAGER 3
10 KING PRESIDENT 1
30 TURNER SALESMAN 4
30 MARTIN SALESMAN 4
30 WARD SALESMAN 4
30 ALLEN SALESMAN 4
14 rows selected.
SQL>
Now things become easier: use that query as a CTE (or a subquery), and apply where clause:
SQL> with temp as
2 (select deptno, ename, job,
3 count(*) over (partition by job) cnt
4 from emp
5 )
6 select deptno, ename, job
7 from temp
8 where cnt >= 4
9 order by job;
DEPTNO ENAME JOB
---------- ---------- ---------
10 MILLER CLERK
30 JAMES CLERK
20 SMITH CLERK
20 ADAMS CLERK
30 TURNER SALESMAN
30 MARTIN SALESMAN
30 WARD SALESMAN
30 ALLEN SALESMAN
8 rows selected.
SQL>
Applied to your query (again, can't test it without any sample data):
with temp as
(select
replace(replace(t.id_contrato,'0999',''),'0998','')as contrato ,
t.num_telefono,
conc.valor_actual,
count(*) over (partition by t.num_telefono) as counter
from tbl_telefono t
inner join cam_tbl_alerta_concentrado conc on t.num_telefono = conc.valor_actual
where id_contrato is not null
and id_contrato not in ('N/A')
)
select contrato, num_telefono, valor_actual
from temp
where counter >= 4;
Join to the selection that have more than 4
SELECT
REPLACE(REPLACE(t.id_contrato,'0999',''),'0998','')as contrato ,
t.num_telefono,
conc.valor_actual,
ct.counter
FROM TBL_TELEFONO t
INNER JOIN (
SELECT num_telefono, COUNT(*) AS counter
FROM TBL_TELEFONO
WHERE origen_tel='TELEFONO CONTRATO'
GROUP BY num_telefono
HAVING COUNT(*) > 4
) ct
ON ct.num_telefono = t.num_telefono
INNER JOIN CAM_TBL_ALERTA_CONCENTRADO conc
ON t.num_telefono = conc.valor_actual
WHERE id_contrato IS NOT NULL
AND id_contrato NOT IN ('N/A')
ORDER BY ct.counter DESC
Wrap the query in another to return only where count > 4
select *
from (
<your query, but without order by>
) x
where count > 4
order by count desc

bind parameter in oracle EBS

i need to add list of values to a bin parameter on report builder in oracle e-business suite
but in this list of values i need the first option is all and other values are result of select statement like the following:
all
10
20
30
....
so if the user clicked on "all" the report will query all departments
if the user clicked on any other specific department, the report will query this specific department
how can i add this "all" option??
I don't use EBS, but I do know Reports and some SQL so - here's my suggestion.
Adding the "all" option is simple - union it with other values. Something like this:
SQL> select value
2 from (select 1 rn, 'all' value from dual
3 union all
4 select 2 rn, to_char(deptno) from dept
5 )
6 order by rn, value;
VALUE
----------------------------------------
all
10
20
30
40
SQL>
Then, in a query, you'd use it as
select e.deptno, e.ename, e.job
from emp e
where e.deptno = case when :par_deptno = 'all' then to_char(e.deptno)
else :par_deptno
end
order by e.deptno, e.ename;
The above example, ran in SQL*Plus (so don't mind a substitution instead of a bind variable):
First, I'm passing 10:
SQL> select e.deptno, e.ename, e.job
2 from emp e
3 where e.deptno = case when '&&par_deptno' = 'all' then to_char(e.deptno)
4 else '&&par_deptno'
5 end
6 order by e.deptno, e.ename;
Enter value for par_deptno: 10
DEPTNO ENAME JOB
---------- ---------- ---------
10 CLARK MANAGER
10 KING PRESIDENT
10 MILLER CLERK
Now, let's try all:
SQL> undefine par_deptno
SQL> /
Enter value for par_deptno: all
DEPTNO ENAME JOB
---------- ---------- ---------
10 CLARK MANAGER
10 KING PRESIDENT
10 MILLER CLERK
20 ADAMS CLERK
20 FORD ANALYST
20 JONES MANAGER
20 SCOTT ANALYST
20 SMITH CLERK
30 ALLEN SALESMAN
30 BLAKE MANAGER
30 JAMES CLERK
30 MARTIN SALESMAN
30 TURNER SALESMAN
30 WARD SALESMAN
14 rows selected.
SQL>
Looks OK to me. Now, how will it look like in EBS, I have no idea.

Oracle- sql query to print odd number of rows when we do not have number data type columns

I was trying to print odd numbers of rows from my table without taking taking help of my numeric cloumns
when I try to execute this query I was getting only first row.
select * from emp3 where mod(rownum,2)=1;
emp3 is my table name.
and when I use my one of the numeric columns in place of rownum I was getting desired output.
select * from emp3 where mod(eid,2)=1 order by eid;
where eid is a numeric column in the table.
But what if do not have a numeric column and I want to print only odd number of rows from the table?
Help me!
Try to execute the below query
select * from (select rownum rn ,column from column_name) where mod(rn,2) <> 0
and please refer to this link for better understanding the concept of rownum https://www.youtube.com/watch?v=QMyw1jumGyQ
If the EID column isn't numeric, then use something that is. For example, ROW_NUMBER gives such an information:
SQL> with temp as
2 (select empno, ename, job sal,
3 row_number() over (order by null) rn
4 from emp
5 )
6 select *
7 from temp
8 where mod(rn, 2) = 1;
EMPNO ENAME SAL RN
---------- ---------- --------- ----------
7369 SMITH CLERK 1
7521 WARD SALESMAN 3
7654 MARTIN SALESMAN 5
7782 CLARK MANAGER 7
7839 KING PRESIDENT 9
7876 ADAMS CLERK 11
7902 FORD ANALYST 13
7 rows selected.
SQL>
Or even ROWNUM you already tried to use:
SQL> with temp as
2 (select empno, ename, job sal,
3 rownum rn
4 from emp
5 )
6 select *
7 from temp
8 where mod(rn, 2) = 1;
EMPNO ENAME SAL RN
---------- ---------- --------- ----------
7369 SMITH CLERK 1
7521 WARD SALESMAN 3
7654 MARTIN SALESMAN 5
7782 CLARK MANAGER 7
7839 KING PRESIDENT 9
7876 ADAMS CLERK 11
7902 FORD ANALYST 13
7 rows selected.
SQL>

Deleting duplicate records with ROWNUM?

I know how to delete duplicate records with ROWID.
Please guide me to delete duplicate records with ROWNUM in Oracle.
That just won't work. From documentation:
For each row returned by a query, the ROWNUM pseudocolumn returns a number indicating the order in which Oracle selects the row from a table or set of joined rows. The first row selected has a ROWNUM of 1, the second has 2, and so on.
Its value is set at the moment you run the query and can be changed, depending on how you fetch data (different ORDER BY will produce different ROWNUM value for the same row). As it is sequential, you can't set "groups" of ROWNUM values (for example, so that it goes from 1, 2, 3 for one set, then 1, 2, 3, 4, 5 for another - you'll always get 1, 2, 3, 4, 5, 6, 7, 8).
If you planned to do something like this:
SQL> create table test as
2 select e.empno, e.deptno, d.dname, e.ename
3 from emp e join dept d on e.deptno = d.deptno;
Table created.
SQL> select * from test order by deptno;
EMPNO DEPTNO DNAME ENAME
---------- ---------- -------------- ----------
7782 10 ACCOUNTING CLARK
7839 10 ACCOUNTING KING
7934 10 ACCOUNTING MILLER
7369 20 RESEARCH SMITH
7902 20 RESEARCH FORD
7566 20 RESEARCH JONES
7900 30 SALES JAMES
7844 30 SALES TURNER
7654 30 SALES MARTIN
7521 30 SALES WARD
7499 30 SALES ALLEN
7698 30 SALES BLAKE
12 rows selected.
SQL> delete from test t
2 where t.empno in (select a.empno
3 from (select t1.empno, t1.deptno, t1.dname, rownum rn
4 from test t1
5 ) a
6 where a.rn > 1
7 );
11 rows deleted.
As you can see, all rows (but one) are duplicates. Here's why:
SQL> rollback;
Rollback complete.
SQL> select a.deptno, a.empno, a.rn, a.rn1
2 from (select t1.empno, t1.deptno, t1.dname, rownum rn,
3 row_number() over (partition by t1.deptno order by null) rn1
4 from test t1
5 ) a;
DEPTNO EMPNO RN RN1
---------- ---------- ---------- ----------
10 7782 2 1
10 7839 1 2
10 7934 3 3
20 7369 5 1
20 7902 4 2
20 7566 6 3
30 7900 7 1
30 7844 8 2
30 7654 9 3
30 7521 10 4
30 7499 11 5
30 7698 12 6
12 rows selected.
See? RN (ROWNUM) has all values from 1, 2, ..., 12. RN1 (ROW_NUMBER, which allows us to set partitions) does the job correctly. So, if you used RN1 instead of RN, it would work:
SQL> delete from test t
2 where t.empno in (select a.empno
3 from (select t1.empno, t1.deptno, t1.dname, rownum rn,
4 row_number() over (partition by t1.deptno order by null) rn1
5 from test t1
6 ) a
7 where a.rn1 > 1
8 );
9 rows deleted.
SQL> select * From test;
EMPNO DEPTNO DNAME ENAME
---------- ---------- -------------- ----------
7782 10 ACCOUNTING CLARK
7369 20 RESEARCH SMITH
7900 30 SALES JAMES
SQL>
[EDIT: deleting duplicates #2]
Here's another example which shows how/what to do if you want to delete duplicates. It is based on the "ROWID technique" (although there are another ones too).
Back to the table we've been working with. Suppose that we want to keep only one distinct job per department:
SQL> select deptno, job, dname, empno, ename
2 from test
3 order by deptno, job;
DEPTNO JOB DNAME EMPNO ENAME
---------- --------- -------------- ---------- ----------
10 CLERK ACCOUNTING 7934 MILLER
10 MANAGER ACCOUNTING 7782 CLARK
10 PRESIDENT ACCOUNTING 7839 KING
20 ANALYST RESEARCH 7902 FORD
20 CLERK RESEARCH 7369 SMITH
20 MANAGER RESEARCH 7566 JONES
30 CLERK SALES 7900 JAMES
30 MANAGER SALES 7698 BLAKE
30 SALESMAN SALES 7844 TURNER -- leave
30 SALESMAN SALES 7654 MARTIN -- only
30 SALESMAN SALES 7521 WARD -- one
30 SALESMAN SALES 7499 ALLEN -- salesman
12 rows selected.
in department 10, there are no duplicates - 3 employees, each of them doing their own job
the same goes for department 20
however, in department 30, there are 4 SALESMEN and we want to keep only one - another ones are duplicates
It means that you have to take both columns - DEPTNO and JOB - into account when deleting rows. Let's do that:
SQL> delete from test a
2 where rowid > (select min(rowid)
3 from test b
4 where a.deptno = b.deptno --> take both DEPTNO ...
5 and a.job = b.job --> and JOB into account
6 );
3 rows deleted.
The result: departments 10 and 20 didn't change, but in department 30 now we have only one salesman, just as we wanted:
SQL> select deptno, job, dname, empno, ename
2 from test
3 order by deptno, job;
DEPTNO JOB DNAME EMPNO ENAME
---------- --------- -------------- ---------- ----------
10 CLERK ACCOUNTING 7934 MILLER
10 MANAGER ACCOUNTING 7782 CLARK
10 PRESIDENT ACCOUNTING 7839 KING
20 ANALYST RESEARCH 7902 FORD
20 CLERK RESEARCH 7369 SMITH
20 MANAGER RESEARCH 7566 JONES
30 CLERK SALES 7900 JAMES
30 MANAGER SALES 7698 BLAKE
30 SALESMAN SALES 7844 TURNER
9 rows selected.
SQL>

Oracle SQL Count of Sum

I am trying to get the Count of a sum using a case statement and I am getting the below error -
not a single-group function
Is it possible to do the count of a Sum?
count(case when sum(ern.hours) >0 then 1 end)
You could do a SUM(ern.hours) in a subquery and then do the following:
SUM(CASE WHEN hours_sum > 0 THEN 1 ELSE 0 END)
An example:
SELECT row_a, row_b, SUM(CASE WHEN hours_sum > 0 THEN 1 ELSE 0 END)
FROM
(SELECT row_a, row_b, sum(ern.hours) AS hours_sum
FROM table_name AS ern
GROUP BY row_a, row_b) sub_q
GROUP BY row_a, row_b;
It is certainly possible to do something like what you are showing. But is that really what you ARE trying to do?
Here is an example based on the EMP table in the SCOTT schema. The table shows 14 employees (14 rows) in three departments. I will count in how many departments the sum of commissions is greater than zero:
select count(case when sum(comm) > 0 then 1 end) as depts_with_commissions
from scott.emp
group by deptno
;
DEPTS_WITH_COMMISSIONS
----------------------
1
I don't see the query throwing an error on this. Perhaps you are selecting OTHER things also, in the same SELECT clause?
The result is correct: only employees in Dept 30 have commissions.
select empno, ename, deptno, comm
from scott.emp
order by deptno, comm
;
EMPNO ENAME DEPTNO COMM
---------- ---------- ---------- ----------
7782 CLARK 10
7839 KING 10
7934 MILLER 10
7566 JONES 20
7902 FORD 20
7876 ADAMS 20
7369 SMITH 20
7788 SCOTT 20
7844 TURNER 30 0
7499 ALLEN 30 300
7521 WARD 30 500
7654 MARTIN 30 1400
7900 JAMES 30
7698 BLAKE 30
Try this:
select count(count(1)) MGR_WITH_MORE_THAN_1_SUB
from scott.emp
group by mgr
having count(1) > 1;
MGR_WITH_MORE_THAN_1_SUB
------------------------
3
It counts the number of managers with more than 1 direct subordinates, but it relies on a quirk of nested aggregate functions.
While this one
select count(sum(comm)) DEPTS_WITH_COMMISSIONS
from scott.emp
group by DEPTNO
having sum(comm) > 0;
DEPTS_WITH_COMMISSIONS
----------------------
1
Counts departments with commissions greater than 0 using the same quirk.