Multi level selecting and function in a Oracle IQ database - oracle

There i a simplified table myowner.mydable with at least columns order_nr,the_days, and i us a multilevel select-query
select * from (
select
The sum(..) function does not work in a inner select-query. How to do use a function in a inner select???
(select sum(the_days) from myowner.mydable where order_nr=confnr) "thedays",--this is a line 4
confnr as order_nr
from (
select order_nr as confnr,the_days from myowner.mydable WHERE order_nr='5276751'
) as t
union all
And there i get an another order_nr
select
(select sum(the_days) from myowner.mydable where order_nr=confnr) "thedays",
confnr as order_nr
from (
select order_nr as confnr,the_days from myowner.mydable WHERE order_nr='5276751'
) as t
) as t2
Select (.....) as t works. But select ((.....) as t union all (.....) as t) as t2 gives an error:
Could not execute statement.
Feature, scalar value subquery (at line 4) outside of a top level SELECT
list, is not supported.
-- (opt_Select.cxx 2238)
SQLCODE=-1001030, ODBC 3 State="HY000"
Line 1, column 1
How to get rid from the error?

If you need execute this query often, you can try to create view based on this query and use it.
Also, your subquery looks strange. This:
select
(select sum(the_days) from myowner.mydable where order_nr=confnr) "thedays",
confnr as order_nr
from (
select order_nr as confnr,the_days from myowner.mydable WHERE order_nr='5276751'
) as t
is equal to this:
select sum(the_days), order_nr from myowner.mydable where order_nr = '5276751'
group by order_nr
UPD Full query you can transform like this:
select t.category, t.def_or_indef, t.book_date, t.book_code, t.revenue,
t2.conf_nr,
t2.mydays,
t.revenue / t2.mydays
from (select category, def_or_indef, book_date, book_code,
revenue,
confnr as conf_nr
from (select CASE WHEN status = 'status1' OR status = 'status2' THEN 'category1' ELSE 'category2' END AS category,
CASE WHEN status = 'status1' OR status = 'status2' THEN 'definite' ELSE 'indefinite' END AS def_or_indef,
book_date,
book_code,
revenue,
conf_nr as confnr
from myowner.mydable
WHERE days > 0
AND book_date IS NOT NULL
AND DATE(dateadd(year,-1,dateadd(day,-day(today()),today()))) < book_date
AND book_date <= date(dateadd(day,-day(today()),today()))) as t
union all
select .. from ( select .. WHERE .. AND DATE(dateadd(day,-day(today()),today())) < resv_date and resv_date < today()
) as t,
(select conf_nr, sum(days) as mydays
from myowner.mydable
group by conf_nr) t2

I give a real query:
select * from (
select
category, def_or_indef, book_date, book_code,
(select sum(days) from myowner.mydable where conf_nr=confnr) as mydays,
revenue, confnr as conf_nr,
revenue / (select sum(days) from myowner.mydable where conf_nr=confnr) as adr
from (
select
CASE WHEN status = 'status1' OR status = 'status2' THEN 'category1' ELSE 'category2' END AS category,
CASE WHEN status = 'status1' OR status = 'status2' THEN 'definite' ELSE 'indefinite' END AS def_or_indef,
book_date, book_code, revenue, conf_nr as confnr
from myowner.mydable
WHERE days > 0 AND book_date IS NOT NULL AND
DATE(dateadd(year,-1,dateadd(day,-day(today()),today()))) < book_date AND book_date <= date(dateadd(day,-day(today()),today()))
) as t
union all
select .. from ( select .. WHERE .. AND
DATE(dateadd(day,-day(today()),today())) < resv_date and resv_date < today()
) as t
) as t2
Can you give working equal to this?

Related

This query giving error, While executing this syntax error comes for AS LastYearVolumeBilled

Error comes on AS LastYearVolumeBilled this line how to add two case when in one select statement
select 'R-1' as Year,
(case when SDBM_MONTH_YR = to_number(extract(year from sysdate) || '04')then
round((sum(SDBM_BILLED_UNITS)/avg(sdbm_billing_days))/1000,2)
end )AS CurrentYearVolumeBilled
FROM t_servicedetail_billing
where SDBM_MONTH_YR= to_number(extract(year from sysdate) || '04')
group by SDBM_MONTH_YR ,
(CASE WHEN SDBM_MONTH_YR = to_number( extract(year from add_months(sysdate,-12)) || '04')
THEN round((sum(SDBM_BILLED_UNITS)/avg(sdbm_billing_days))/1000,2)
END)AS LastYearVolumeBilled
FROM t_servicedetail_billing
where SDBM_MONTH_YR= to_number( extract(year from add_months(sysdate,-12)) || '04')
group by SDBM_MONTH_YR;
These are two different queries, so one option might be to treat them as such by using a CTE (as my example shows) or as subqueries.
WITH
t_curr
AS
( SELECT 'R-1' AS year,
(CASE
WHEN sdbm_month_yr =
TO_NUMBER (EXTRACT (YEAR FROM SYSDATE) || '04')
THEN
ROUND (
(SUM (sdbm_billed_units) / AVG (sdbm_billing_days))
/ 1000,
2)
END) AS currentyearvolumebilled
FROM t_servicedetail_billing
WHERE sdbm_month_yr = TO_NUMBER (EXTRACT (YEAR FROM SYSDATE) || '04')
GROUP BY sdbm_month_yr),
t_last
AS
( SELECT 'R-1' AS year,
(CASE
WHEN sdbm_month_yr =
TO_NUMBER (
EXTRACT (YEAR FROM ADD_MONTHS (SYSDATE, -12))
|| '04')
THEN
ROUND (
(SUM (sdbm_billed_units) / AVG (sdbm_billing_days))
/ 1000,
2)
END) AS lastyearvolumebilled
FROM t_servicedetail_billing
WHERE sdbm_month_yr =
TO_NUMBER (
EXTRACT (YEAR FROM ADD_MONTHS (SYSDATE, -12)) || '04')
GROUP BY sdbm_month_yr)
SELECT a.year, a.currentyearvolumebilled, b.lastyearvolumebilled
FROM t_curr a CROSS JOIN t_last b;
How to add more subqueries (simplified):
with
t_curr_r1 as
(select 'R-1' as year, ... from ...),
t_curr_r2 as
(select 'R-2' as year, ... from ...),
t_curr_r3 as
(select 'R-3' as year, ... from ...),
--
t_last_r1
(select 'R-1' as year, ... from ...),
t_last_r2 as
(select 'R-2' as year, ... from ...),
t_last_r3 as
(select 'R-3' as year, ... from ...),
--
select c1.year, c1.currentyearvolumebilled,
c2.currentyearvolumebilled,
c3.currentyearvolumebilled,
...
l1.lastyearvolumebilled,
l2.lastyearvolumebilled,
l3.lastyearvolumebilled,
...
from t_curr_r1 c1 cross join t_curr_r2 c2
cross join t_curr_r3 c3
...
cross join t_last_r1 l1
cross join t_last_r2 l2
cross join t_last_r3 l3
...
You have repeated your query twice. You don't need a case statement cause you have the same condition in where clause. So the correct query might be -
select 'R-1' as Year,
round((sum(SDBM_BILLED_UNITS)/avg(sdbm_billing_days))/1000,2)
END AS CurrentYearVolumeBilled
FROM t_servicedetail_billing
WHERE SDBM_MONTH_YR = to_number(extract(year from sysdate) || '04')

Oracle adding a subquery in a CTE

I have the following setup, which works fine and generates output as expected.
I'm trying to add the locations subquery into the CTE so my output will have a random location_id for each row.
The subquery is straight forward and should work but I am getting syntax errors when I try to place it into the 'data's CTE. I was hoping someone could help me out.
CREATE TABLE employees(
employee_id NUMBER(6),
emp_name VARCHAR2(30)
);
INSERT INTO employees(
employee_id,
emp_name
) VALUES
(1, 'John Doe');
INSERT INTO employees(
employee_id,
emp_name
) VALUES
(2, 'Jane Smith');
INSERT INTO employees(
employee_id,
emp_name
) VALUES
(3, 'Mike Jones');
CREATE TABLE locations AS
SELECT level AS location_id,
'Door ' || level AS location_name
FROM dual
CONNECT BY level <=
with rws as (
select level rn from dual connect by level <= 5 ),
data as ( select e.*,round (dbms_random.value(1,5)
) n from employees e)
select employee_id,
emp_name,
trunc (sysdate) + dbms_random.value (0, 5) AS random_date
from rws
join data d on rn <= n
order by employee_id;
-- trying to make this work
with rws as ( select level rn from dual connect by level <= 5 ),
data as ( select e.*, loc.location_id = (
select location_id
from locations order by dbms_random.value()
fetch first 1 row only
),
round (dbms_random.value(1,5)
) n from employees e )
select employee_id,
emp_name,
trunc (sysdate) + dbms_random.value (0, 5) AS random_date
from rws
join data d on rn <= n
order by employee_id;
You need to alias the subquery column expression, rather than trying to assign it to a [variable] name. So instead of this:
with rws as ( select level rn from dual connect by level <= 5 ),
data as ( select e.*, loc.location_id = (
select location_id
from locations order by dbms_random.value()
fetch first 1 row only
),
round (dbms_random.value(1,5)
) n from employees e )
you would do this:
with rws as (
select level rn
from dual
connect by level <= 5
),
data as (
select e.*,
(
select location_id
from locations
order by dbms_random.value()
fetch first 1 row only
) as location_id,
round (dbms_random.value(1,5)) as n
from employees e
)
db<>fiddle
But yes, you'll get the same location_id for each row, which probably isn't what you want.
There are probably better ways to avoid it (or to approach whatever you're actually trying to achieve) but one option is to force the subquery to be correlated by adding something like:
where location_id != -1 * e.employee_id
db<>fiddle
although that might be expensive. It's probably worth asking a new question about that specific aspect.
I am getting the same location_id for every employee_id, which I don't want either.
The subquery is in the wrong place then; move it to the main query, and correlate against both ID and n:
with rws as (
select level rn
from dual
connect by level <= 5
),
data as (
select e.*,
round (dbms_random.value(1,5)) as n
from employees e
)
select d.employee_id,
d.emp_name,
(
select location_id
from locations
where location_id != -1 * d.employee_id * d.n
order by dbms_random.value()
fetch first 1 row only
) as location_id,
trunc (sysdate) + dbms_random.value (0, 5) AS random_date
from rws r
join data d on r.rn <= d.n
order by d.employee_id;
db<>fiddle
Or move the location part to a new CTE, I suppose, with its own row number; and join that on one of your other generated values.

Pl / SQL Oracle helps to run a Date in Subquery

How could I get the date of the Maximum Value, by means of a subquery
I can't put the Date in the Main query because I would have to add it to the group by it would bring me a lot of data
Here is the Code:
SELECT MAX (A1.VALOR) AS VALOR,
(SELECT sq1.FECHA
FROM VARIABLE_VALORES_SMEC sq1
WHERE sq1.ID_AGENTE = A1.ID_AGENTE)
MES, -- {<-- Here is the Problem}
(SELECT CODIGO_AGENTE
FROM AGENTES
WHERE ID_AGENTE = A1.ID_AGENTE)
Agentess,
(SELECT NOMBRE_AGENTE
FROM AGENTES
WHERE ID_AGENTE = A1.ID_AGENTE)
Nombre_Agente
FROM VARIABLE_VALORES_SMEC A1
WHERE A1.VALOR < '1'
AND A1.VALOR != '0'
AND A1.ID_AGENTE IN (SELECT C1.ID_AGENTE
FROM VARIABLE_VALORES_SMEC C1
WHERE A1.FECHA = C1.FECHA)
AND A1.ID_AGENTE IN (SELECT B1.ID_AGENTE
FROM AGENTES B1
WHERE ID_CATEGORIA_AGENTE = 'AC006')
AND (A1.FECHA BETWEEN (ADD_MONTHS (TO_DATE ( :FECHAIN, 'MM/DD/YYYY'),
-1))
AND (LAST_DAY (
ADD_MONTHS (
TO_DATE ( :FECHAIN, 'MM/DD/YYYY'),
-1))))
AND A1.ID_VARIABLE LIKE '%_calc_total_pot#%'
GROUP BY ID_AGENTE
Am I correct that you need (fecha) for maximum A1.VALOR?
If - yes, you can use the following query, or if - no, just replace A1.VALOR with the required column in keep() clause:
SELECT MAX (A1.VALOR) AS VALOR,
max(A1.FECHA)keep(dense_rank first order by A1.VALOR desc) MES, -- A1.VALOR is used here as sort key, replace it with what you want
(SELECT CODIGO_AGENTE
FROM AGENTES
WHERE ID_AGENTE = A1.ID_AGENTE)
Agentess,
(SELECT NOMBRE_AGENTE
FROM AGENTES
WHERE ID_AGENTE = A1.ID_AGENTE)
Nombre_Agente
FROM VARIABLE_VALORES_SMEC A1
WHERE A1.VALOR < '1'
AND A1.VALOR != '0'
AND A1.ID_AGENTE IN (SELECT C1.ID_AGENTE
FROM VARIABLE_VALORES_SMEC C1
WHERE A1.FECHA = C1.FECHA)
AND A1.ID_AGENTE IN (SELECT B1.ID_AGENTE
FROM AGENTES B1
WHERE ID_CATEGORIA_AGENTE = 'AC006')
AND (A1.FECHA BETWEEN (ADD_MONTHS (TO_DATE ( :FECHAIN, 'MM/DD/YYYY'),
-1))
AND (LAST_DAY (
ADD_MONTHS (
TO_DATE ( :FECHAIN, 'MM/DD/YYYY'),
-1))))
AND A1.ID_VARIABLE LIKE '%_calc_total_pot#%'
GROUP BY ID_AGENTE
You can use row_number analytical function to fetch one record for which value is highest and use the fecha of that record. Use following sub query:
(Select fecha from
(SELECT sq1.FECHA, row_number() over (order by sq1.value desc nulls last) as rn
FROM VARIABLE_VALORES_SMEC sq1
WHERE sq1.ID_AGENTE = A1.ID_AGENTE)
Where rn = 1) MES

procedure failurecompilation

I have an existing procedure which creates a table adwstg.switchhold_notificatn_stg
Suddenly it is throwing error in creating the table. I didn't change anything the statement.
First I thought the error is with ''No'' . So find & replace '' with '
But it is throwing error at line:
nvl(ba300_z51.sent_650_01, 'No') sent_650_01,
error(27,29): PLS-00103: Encountered the symbol "NO" when expecting one of the following: * & = - + ; < / > at in is mod remainder not rem <> or != or ~= >= <= <> and or like like2 like4 likec between || multiset member submultiset***
Below is the query :
create table adwstg.switchhold_notificatn_stg nologging parallel (degree 8) compress as
select distinct
bad3700.createdon,
bad3700.uc_pod_ext,
bpc.cacont_acc,
bad3700.notificatn,
bad3700.nfcat_code,
nvl(ba300_z51.sent_650_01, ''No'') sent_650_01,
decode(ba300_z51.sent_650_01,''No'',''--'',''Yes'',to_char(ba300_z51.ucswmsgdat,''yyyymmdd''),''--'') date_sent_650_01,
nvl(to_char(ba300_z51.ucswmsgtim,''hh24:mi:ss''),''--'') time_sent_650_01,
nvl(ba300_z52.received_650_02, ''No'') received_650_02,
decode(ba300_z52.received_650_02,''No'',''--'',''Yes'',to_char(ba300_z52.ucswmsgdat,''yyyymmdd''),''--'') date_received_650_02,
nvl(to_char(ba300_z52.ucswmsgtim,''hh24:mi:ss''),''--'') time_received_650_02,
nvl(ba300_z20.received_814_20, ''No'') received_814_20,
decode(ba300_z20.received_814_20,''No'',''--'',''Yes'',to_char(ba300_z20.ucswmsgdat,''yyyymmdd''),''--'') date_received_814_20,
nvl(to_char(ba300_z20.ucswmsgtim,''hh24:mi:ss''),''--'') time_received_814_20,
case
when trim(bad3700.nfcat_code) = ''SH01'' and zet.ext_ui is not null then ''ADDED''
when trim(bad3700.nfcat_code) = ''SH01'' and zet.ext_ui is null then ''NOT PROCESSED''
when trim(bad3700.nfcat_code) in (''SH02'',''SH03'') and zet.ext_ui is null then ''REMOVED''
when trim(bad3700.nfcat_code) in (''SH02'',''SH03'') and zet.ext_ui is not null then ''NOT PROCESSED''
else ''NOT PROCESSED''
end work_order_check
from
(select distinct *
from
(select
trunc(createdon) createdon,
trim(notificatn) notificatn,
trim(uc_pod_ext) uc_pod_ext,
trim(not_type) not_type,
trim(nfcat_code) nfcat_code,
row_number () over (partition by trim(uc_pod_ext),trunc(createdon) order by trim(notificatn) desc) rnum
from birpt.bic_azfc_ds3700
where upper(trim(not_type)) = ''SH''
and trim(bic_zdiscstat) = ''E0010'')
where rnum = 1
) bad3700
left outer join
(
select distinct ucinstalla, uc_pod_ext, datefrom, dateto
from birpt.bi0_qucinstalla
where objvers = ''A''
) bqi
on (trim(bad3700.uc_pod_ext) = trim(bqi.uc_pod_ext)
and trunc(bad3700.createdon) between bqi.datefrom and bqi.dateto)
left outer join
(
select distinct cacont_acc, ucinstalla, ucmovein_d, ucmoveoutd
from birpt.bi0_puccontract
where objvers = ''A''
) bpc
on (trim(bqi.ucinstalla) = trim(bpc.ucinstalla)
and trunc(bad3700.createdon) between bpc.ucmovein_d and bpc.ucmoveoutd)
left outer join
(select distinct *
from
(select
trim(ucswtpodex) ucswtpodex,
trunc(ucswmsgdat) ucswmsgdat,
ucswmsgtim,
case --650_01 CHECK
when trim(uc_mdcat) = ''Z51'' then ''Yes''
else ''No''
end sent_650_01,
row_number () over (partition by trim(ucswtpodex), trunc(ucswmsgdat) order by trunc(ucswmsgdat) desc, ucswmsgtim desc) rnum
from birpt.bic_azudeds0300
where trim(uc_mdcat) = ''Z51'')
where rnum = 1) ba300_z51
on (trim(bad3700.uc_pod_ext) = trim(ba300_z51.ucswtpodex)
and trunc(bad3700.createdon)= trunc(ba300_z51.ucswmsgdat))
left outer join
(select distinct *
from
(select
trim(ucswtpodex) ucswtpodex,
trunc(ucswmsgdat) ucswmsgdat,
ucswmsgtim,
case --650_02 CHECK
when trim(uc_mdcat) = ''Z52'' then ''Yes''
else ''No''
end received_650_02,
row_number () over (partition by trim(ucswtpodex), trunc(ucswmsgdat) order by trunc(ucswmsgdat) desc, ucswmsgtim desc) rnum
from birpt.bic_azudeds0300
where trim(uc_mdcat) = ''Z52'')
where rnum = 1) ba300_z52
on (trim(bad3700.uc_pod_ext) = trim(ba300_z52.ucswtpodex)
and trunc(bad3700.createdon)= trunc(ba300_z52.ucswmsgdat))
left outer join
(select distinct *
from
(select
trim(ucswtpodex) ucswtpodex,
trunc(ucswmsgdat) ucswmsgdat,
ucswmsgtim,
case --814_20 CHECK
when trim(uc_mdcat) = ''Z20'' then ''Yes''
else ''No''
end received_814_20,
row_number () over (partition by trim(ucswtpodex), trunc(ucswmsgdat) order by trunc(ucswmsgdat) desc, ucswmsgtim desc) rnum
from birpt.bic_azudeds0300
where trim(uc_mdcat) = ''Z20'')
where rnum = 1) ba300_z20
on (trim(bad3700.uc_pod_ext) = trim(ba300_z20.ucswtpodex)
and trunc(bad3700.createdon)= trunc(ba300_z20.ucswmsgdat))
left outer join
(select distinct ext_ui
from isurpt.zcs_esiid_tamper
) zet
on (trim(bad3700.uc_pod_ext) = trim(zet.ext_ui));
If you remove all doubled single quotes (perform replace function in any text editor), your code will be valid (as far as syntax is concerned).
I don't have your tables to test it, and there are too many of them with too many columns to create a test case by myself.
The question is: why did you double them in the first place?

How to get count by using UNION operator

i'm trying to get total count by using UNION operator but it gives wrong count.
select count(*) as companyRatings from (
select count(*) hrs from (
select distinct hrs from companyA
)
union
select count(*) financehrs from (
select distinct finance_hrs from companyB
)
union
select count(*) hrids from (
select regexp_substr(hr_id,'[^/]+',1,3) hrid from companyZ
)
union
select count(*) cities from (
select regexp_substr(city,'[^/]+',1,3) city from companyY
)
);
individual query's working fine but total count not matching.
individual results here: 12 19 3 6
present total count: 31
Actual total count:40.
so there is any alternate solution without UNION operator?
To add values you'd use +. UNION is to add data sets.
select
(select count(distinct hrs) from companyA)
+
(select count(distinct finance_hrs) from companyB)
+
(select count(regexp_substr(hr_id,'[^/]+',1,3)) from companyZ)
+
(select count(regexp_substr(city,'[^/]+',1,3)) from companyY)
as total
from dual;
But I agree with juergen d; you should not have separate tables per company in the first place.
Edit. Updated query using Sum
select sum(cnt) as companyRatings from
(
select count(*) as cnt from (select distinct hrs from companyA)
union all
select count(*) as cnt from (select distinct finance_hrs from companyB)
union all
select count(*) as cnt from (select regexp_substr(hr_id,'[^/]+',1,3) hrid from companyZ)
union all
select count(*) as cnt from (select regexp_substr(city,'[^/]+',1,3) city from companyY)
)
Previous answer:
Try this
SELECT (
SELECT count(*) hrs
FROM (
SELECT DISTINCT hrs
FROM companyA
)
)
+
(
SELECT count(*) financehrs
FROM (
SELECT DISTINCT finance_hrs
FROM companyB
)
)
+
(
SELECT count(*) hrids
FROM (
SELECT regexp_substr(hr_id, '[^/]+', 1, 3) hrid
FROM companyZ
)
)
+
(
SELECT count(*) cities
FROM (
SELECT regexp_substr(city, '[^/]+', 1, 3) city
FROM companyY
)
)
AS total_count
FROM dual

Resources