I've created this query in PL SQL where i have to check how much time an operation takes.
set line 2222
set pages 0
set feedback off
col EVENT for a35
col SQL_ID for a13
col ET for 9999
col mymac for a15
col username for a12
SELECT MAX(a.last_call_et)
FROM gv\\$session a, gv\\$sqlarea c
where c.address= a.sql_address
and c.hash_value = a.sql_hash_value
and a.username='XXXX'
and a.last_call_et>600
order by a.last_call_et;
I want to modify this query in a way that show me how many rows I've got from result. For example, if my query result will have two rows, I want to show '2'
I think you can use count aggregate function along with existing max aggregate function as following:
SELECT MAX(a.last_call_et),
count(1) as total_rows --<-- this
FROM gv\\$session a, gv\\$sqlarea c
where c.address= a.sql_address
and c.hash_value = a.sql_hash_value
and a.username='XXXX'
and a.last_call_et>600
-- order by a.last_call_et; this order by is of no use
Cheers!!
As it is SQL*Plus, then a little bit of its formatting could do the job. For example:
SQL> break on report
SQL> compute count of ename on report
SQL>
SQL> select ename from emp where deptno = 10;
ENAME
----------
CLARK
KING
MILLER
----------
3
SQL>
Related
I have created a query in PLSQL to search customer records from the tables. But still has some limitations. In the &CUSTOMER_ID Search field If I Put IN% OR DL100056* It will search All the details which start with IN or giving the exact DL details as output. I want to search multiple values like in the customer Id field I wanna search DL100056,DL1000365,DL1000652 likewise. But my current query not giving multiple outputs.
SELECT
DISTINCT CUSINFO.CUSTOMER_ID AS DEALER_CODE,
CUSINFO.name AS DEALER_NAME,
CUSINFO.CORPORATE_FORM AS FORM_OF_BUSINESS,
C.corporate_form_desc AS FORM_OF_BUSINESS_DESCRIPTION,
ifsapp.Customer_Info_Address_Api.Get_Address1(CUSINFO.customer_id,1) "ADDRESS 1",
ifsapp.Customer_Info_Address_Api.Get_Address2(CUSINFO.customer_id,1) "ADDRESS 2",
CREDTIN.credit_limit AS CREDIT_LIMIT,
CREDTIN.allowed_due_amount AS ALLOWED_DUE_AMOUNT,
CREDTIN.allowed_due_days AS ALLOWED_DUE_DAYS,
ORDERC.salesman_code AS SALESMAN_CODE,
BDA.name AS SALESMAN_NAME,
ORDERC.discount AS DISCOUNT,
(select LISTAGG(c.value,' / ') within group (order by c.value) from ifsapp.COMM_METHOD c
where c.method_id_db='PHONE' and c.identity=CUSINFO.customer_id ) "Phone",
(select LISTAGG(c.value,' / ') within group (order by c.value) from ifsapp.COMM_METHOD c
where c.method_id_db='MOBILE' and c.identity=CUSINFO.customer_id) "Mobile",
(select LISTAGG(c.value,' / ') within group (order by c.value) from ifsapp.COMM_METHOD c
where c.method_id_db='FAX' and c.identity=CUSINFO.customer_id) "Fax",
CUSINFO.identifier_reference as IDENTIFIER_REFERENCE
FROM
ifsapp.CUSTOMER_INFO CUSINFO
LEFT JOIN
ifsapp.CUSTOMER_INFO_ADDRESS CUSADD ON CUSINFO.customer_id=CUSADD.customer_id
LEFT JOIN
ifsapp.CUSTOMER_INFO_CONTACT CUSCONT ON CUSINFO.customer_id=CUSCONT.customer_id
LEFT JOIN
ifsapp.CUSTOMER_CREDIT_INFO_CUST CREDTIN ON CUSINFO.customer_id=CREDTIN.identity
LEFT JOIN
ifsapp.CUST_ORD_CUSTOMER_ENT ORDERC ON CUSINFO.customer_id=ORDERC.customer_id
LEFT JOIN
ifsapp.Comm_Method COMM ON CUSINFO.customer_id=COMM.customer_id
LEFT JOIN
ifsapp.CORPORATE_FORM C ON CUSINFO.corporate_form=C.CORPORATE_FORM
LEFT JOIN
ifsapp.SALES_PART_SALESMAN_LOV BDA ON ORDERC.salesman_code=BDA.salesman_code
WHERE CUSINFO.CUSTOMER_ID LIKE '&CUSTOMER_ID'
It can't work that way; one option is to use such a query (I don't have your tables so I used Scott's DEPT): it splits parameter values (separated by comma) into rows and uses them as a subquery. So, what you need is lines #3 - 5 (adjusted to your table / column name).
SQL> select deptno, dname, loc
2 from dept
3 where deptno in (select to_number(regexp_substr('&&par_deptno', '[^,]+', 1, level))
4 from dual
5 connect by level <= regexp_count('&&par_deptno', ',') + 1
6 )
7 order by deptno;
Enter value for par_deptno: 10
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
SQL> undefine par_deptno
SQL> /
Enter value for par_deptno: 20,40
DEPTNO DNAME LOC
---------- -------------- -------------
20 RESEARCH DALLAS
40 OPERATIONS BOSTON
SQL>
please format your sql better, it is very difficult to understand the logic behind the query if its is unreadable.
You could try by using LIKE 'DL%'. This will look for all strings starting with DL. Another solution, if the code doesn't always start with 'DL', is using a substring on the code to get the first few characters, then adding '%'
hope this helped
I'm using Oracle 19c. I'm not allowed to have Sub-Selects with ORDER BY.
I need to get certain columns from a Max-ID row as a Sub-Select (because of a Hibernate Formula):
Plans.java PLANS_T Domain Object
#Formula(value="
(SELECT wf.last_changed_date
FROM plan_workflow_t wf
WHERE wf.plan_id = id and rownum = 1 order by id desc)
")
Is there a way to rewrite this without ORDER BY/rownum but keep it a Sub-Select?
I can't do max(last_changed_date). The Max LastChangedDate can be on a different row than the latest row by ID; this means that the latest row by ID would have a NULL LastChangedDate, and that's what I have to return. So I need to grab specific columns (in this case last_changed_date) from the Max-ID row.
I don't know Hibernate so I can't tell whether any of these will actually help; try and see.
Just to know what date format is being used:
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
Sample data:
SQL> select * from plan_workflow_t order by plan_id;
PLAN_ID LAST_CHANG
---------- ----------
1 20.07.2020
2 13.05.2020
3 15.02.2018 --> you need this date value
The most straightforward query:
SQL> select a.last_changed_date
2 from plan_workflow_t a
3 where a.plan_id = (select max(b.plan_id) from plan_workflow_t b);
LAST_CHANG
----------
15.02.2018
Or, an analytic function, perhaps?
SQL> select max(x.retval) retval
2 from (select first_value(a.last_changed_date) over (order by a.plan_id desc) retval
3 from plan_workflow_t a
4 ) x;
RETVAL
----------
15.02.2018
SQL>
I have the following sql query that I m not able to process since this afternoon.
I have seen lot of threads about this issue but I m not getting it right, I believe that I m miss understanding this one topic that is shaming my day.
SELECT
cor.c_order_id, cor.totallines,cor.documentno,cbp.name
FROM
c_orderline col
LEFT JOIN c_order cor ON cor.c_order_id = col.c_order_id
LEFT join c_bpartner cbp on cbp.c_bpartner_id = cor.c_bpartner_id
WHERE
cor.issotrx = 'Y'
and cor.docstatus not in ('DR','IP')
AND cor.salesrep_id = 1037317
and col.qtyordered <> 0
and cor.dateordered between SYSDATE - 30 and SYSDATE + 30
AND col.c_orderline_id NOT IN (
SELECT
cil.c_orderline_id
FROM
c_invoiceline cil
WHERE
cil.c_orderline_id IS NOT NULL
)
group by cor.c_order_id, cor.documentno
order by cor.c_order_id, cor.documentno
What I m doing wrong ??
A simplified example, based on Scott's EMP table.
This is what you did:
SQL> select deptno, job
2 from emp
3 group by deptno;
select deptno, job
*
ERROR at line 1:
ORA-00979: not a GROUP BY expression
As you can see, Oracle marked the culprit - the JOB column.
Therefore, if you want to use a GROUP BY clause (which is correct, but - you'd get the same result using DISTINCT; these two should not be used together. GROUP BY is usually used with aggregates such as min, max, avg and such), then put all columns into the GROUP BY:
SQL> select deptno, job
2 from emp
3 group by deptno, job;
DEPTNO JOB
---------- ---------
20 CLERK
30 SALESMAN
20 MANAGER
30 CLERK
10 PRESIDENT
30 MANAGER
10 CLERK
10 MANAGER
20 ANALYST
9 rows selected.
Or, as I said - using DISTINCT:
SQL> select distinct deptno, job
2 from emp;
DEPTNO JOB
---------- ---------
20 CLERK
30 SALESMAN
20 MANAGER
30 CLERK
10 PRESIDENT
30 MANAGER
10 CLERK
10 MANAGER
20 ANALYST
9 rows selected.
SQL>
group by is used for aggregate functions like sum(), max(), min() etc. What value are you calculating in groups?
remove the group by and your query looks good besides that
To correct the error this query is producing you need to
group by cor.c_order_id, cor.totallines,cor.documentno,cbp.name
Group by all the columns that are in the select statement and are not part of aggregate function.
What else is a problem?
Here is the DEMO
In this demo you will see that the query works(with the correction I have suggested), but as I asked, what else is a problem to you. Do elaborate so we can help. Cheers!
I have a preexisting table (MYORIGTABLE) in SQL and I would like to add a column which is a random sample from a column in another table (RANDNUM10). The other table is a 1 column sample of random numbers I've predetermined and would like to sample from; column name is RANDVAL. I've tried the following
select
(select randval from
(SELECT randval
FROM RANDNUM10
ORDER BY dbms_random.value)
where rownum=1) as mynum
from MYORIGTABLE
But unfortunately this just gives me the same random number which was sampled from RANDNUM10 repeated for the entire length of MYORIGTABLE. How can I perform the sampling so that every line of MYORIGTABLE gets a newly generated sample?
Thanks,
Christie
This is your query:
select (select randval
from (SELECT randval
FROM RANDNUM10
ORDER BY dbms_random.value
)
where rownum = 1
) as mynum
from MYORIGTABLE;
A common problem with database optimizers -- in this situation -- that that it optimizes away the multiple calls to the subquery. It ends up replacing the subquery with one call.
One way around this is to use a correlated subquery. For this, I would recommend removing one level of nesting:
select (select max(randval) keep (dense_rank first order by dbms_rnadom.value)
from randnum10
where myorigtable.id is not null -- or whatever
) as mynum
from MYORIGTABLE;
I think this will work so the subquery is called 10 times, although a more complex correlation clause might be needed.
Something like this, perhaps?
Test case:
SQL> create table myorigtable (id number);
Table created.
SQL> create table randnum10 (randval number);
Table created.
SQL> insert into myorigtable select level from dual connect by level <= 10;
10 rows created.
SQL> insert into randnum10 select round(dbms_random.value(1, 100)) from dual connect by level <= 10;
10 rows created.
SQL> alter table myorigtable add randval number;
Table altered.
Update:
SQL> update myorigtable m set
2 m.randval = (select x.randval
3 from (select randval, row_number() over (order by randval) rn
4 from randnum10
5 ) x
6 where x.rn = m.id
7 );
10 rows updated.
SQL> select * from myorigtable;
ID RANDVAL
---------- ----------
1 5
2 18
3 29
4 31
5 31
6 62
7 66
8 87
9 94
10 98
10 rows selected.
SQL>
Here is one approach. I assume your RANDNUM10 table has many rows (more rows than MYORIGTABLE), you want to sample the random numbers without replacement (select DISTINCT random values from RANDNUM10) - and therefore the random numbers table has enough rows - at least as many as MYORIGTABLE - and you need to add the column to the result set of a SELECT query, rather than to the stored table. (If you need to store the result in an additional column, then you must first add the column if it doesn't already exist, and use the SELECT query below in an UPDATE statement.)
The strategy is simple: associate arbitrary row numbers to the smaller table (with values 1, 2, ..., N where N is the row count), and associate random row numbers to the rows in the random numbers table. Both can be done with ROW_NUMBER()... - the first one can be ordered by NULL since all the randomness we need will come from the other table's row numbers anyway. Then JOIN the two tables on the row number thus added to both tables.
For illustration I created MYORIGTABLE as a copy of SCOTT.EMP, selecting only a few columns from that table. Here's what the query looks like, and the output using that as MYORIGTABLE.
Setup:
create table myorigtable as select empno, ename, job, deptno from scott.emp;
create table randnum10 ( randval ) as
select dbms_random.value() from dual connect by level <= 1000;
Query and output:
select a.empno, a.ename, a.job, a.deptno, b.randval
from (
select empno, ename, job, deptno, row_number() over (order by null) as rn
from myorigtable
) a
inner join
(
select randval, row_number() over (order by dbms_random.value()) as rn
from randnum10
) b
on a.rn = b.rn
;
EMPNO ENAME JOB DEPTNO RANDVAL
----- ---------- --------- ------- ----------
7369 SMITH CLERK 20 .991998901
7499 ALLEN SALESMAN 30 .448133242
7521 WARD SALESMAN 30 .136242235
7566 JONES MANAGER 20 .443347421
7654 MARTIN SALESMAN 30 .836931008
7698 BLAKE MANAGER 30 .361437867
7782 CLARK MANAGER 10 .433786615
7788 SCOTT ANALYST 20 .285173363
7839 KING PRESIDENT 10 .063840361
7844 TURNER SALESMAN 30 .825888729
7876 ADAMS CLERK 20 .818415041
7900 JAMES CLERK 30 .150180080
7902 FORD ANALYST 20 .442389099
7934 MILLER CLERK 10 .086995415
I have a oracle table like
Name Sal Bonus
ABC 400 null
ABC null 5
How to make it single row and remove null data
Name Sal Bonus
ABC 400 5
Please suggest. Using oracle sql.
If you have just two rows, you can use group by clause. And sum values inside select statement.
SELECT T.NAME,SUM(NVL(T.SAL,0))AS Sal,SUM(NVL(T.SAL,0)) AS Bonus
FROM TABLE t
GROUP BY T.NAME
Here the result:
Name Sal Bonus
ABC 400 5
select name, max(sal), max(bonus)
from Table
group by name