oracle insert and complex select. what's wrong? - sql

i have some complex select and result need to place in the table.
I try this:
INSERT INTO SAMGUPS_STATISTIC_STANTION
(SAMGUPS_STATISTIC_STANTION_SEQ.nextval)
(
with PRG as (
select
ID_OBJ
from PEREGON where ID_STAN1=&arrival
),
STN_OBJ as (
select
distinct ID_OBJ_P as ID_OBJ
from TMO start with ID_OBJ=&dispatch
connect by prior ID_OBJ_P=ID_OBJ
),
STAN as (
select
A_TOP.ID_POEZD
,A_TOP.vrsvop
from STN_OBJ inner join A_TOP on A_TOP.ID_OBJ=STN_OBJ.ID_OBJ and A_TOP.KODOP_P in ('01','07')
left join A_POEZD_ATR ATR on ATR.ID_POEZD=A_TOP.ID_POEZD and ATR.VRSVOP=A_TOP.VRSVOP
WHERE ATR.NOM_POEZD LIKE '____'
),
DATA_RESULT as
(
select
/*count(*) over() as TotalCount*/
to_char(&dispatch) as dispatch
,to_char(&arrival) as arrival
...
,ATR.PR_N_V_PZ
from PRG inner join A_TOP on A_TOP.ID_OBJ=PRG.ID_OBJ and A_TOP.KODOP_P in ('03','07')
left join A_POEZD_ATR ATR on ATR.ID_POEZD=A_TOP.ID_POEZD and ATR.VRSVOP=A_TOP.VRSVOP
inner join STAN STN on STN.ID_POEZD = ATR.ID_POEZD
WHERE ATR.NOM_POEZD LIKE '____'
order by A_TOP.ID_POEZD
)
SELECT * FROM DATA_RESULT);
i have error:
Error at Command Line:71 Column:25
Error report:
SQL Error: ORA-32034: unsupported use of WITH clause
32034. 00000 - "unsupported use of WITH clause"
*Cause: Inproper use of WITH clause because one of the following two reasons
1. nesting of WITH clause within WITH clause not supported yet
2. For a set query, WITH clause can't be specified for a branch.
3. WITH clause can't sepecified within parentheses.
*Action: correct query and retry
Whether there is to circumvent these restrictions?
May be possible result of select place into variable and then using variable insert to table?

WITH clause can't sepecified within parentheses.
try rewrite smth like this
INSERT INTO SAMGUPS_STATISTIC_STANTION
with PRG as (
select
ID_OBJ
from PEREGON where ID_STAN1=&arrival
),
STN_OBJ as (
select
distinct ID_OBJ_P as ID_OBJ
from TMO start with ID_OBJ=&dispatch
connect by prior ID_OBJ_P=ID_OBJ
),
STAN as (
select
A_TOP.ID_POEZD
,A_TOP.vrsvop
from STN_OBJ inner join A_TOP on A_TOP.ID_OBJ=STN_OBJ.ID_OBJ and A_TOP.KODOP_P in ('01','07')
left join A_POEZD_ATR ATR on ATR.ID_POEZD=A_TOP.ID_POEZD and ATR.VRSVOP=A_TOP.VRSVOP
WHERE ATR.NOM_POEZD LIKE '____'
),
DATA_RESULT as
(
select
/*count(*) over() as TotalCount*/
to_char(&dispatch) as dispatch
,to_char(&arrival) as arrival
...
,ATR.PR_N_V_PZ
from PRG inner join A_TOP on A_TOP.ID_OBJ=PRG.ID_OBJ and A_TOP.KODOP_P in ('03','07')
left join A_POEZD_ATR ATR on ATR.ID_POEZD=A_TOP.ID_POEZD and ATR.VRSVOP=A_TOP.VRSVOP
inner join STAN STN on STN.ID_POEZD = ATR.ID_POEZD
WHERE ATR.NOM_POEZD LIKE '____'
order by A_TOP.ID_POEZD
)
SELECT SAMGUPS_STATISTIC_STANTION_SEQ.nextval, DATA_RESULT.* FROM DATA_RESULT;

No need for an ORDER BY on an INSERT.
An INSERT is coded like this: INSERT INTO mytable (mycolumn, ...) SELECT ...
Try something like this:
INSERT INTO SAMGUPS_STATISTIC_STANTION
(dispatch, arrival, ..., PR_N_V_PZ)
select
to_char(&dispatch) as dispatch
,to_char(&arrival) as arrival
...
,ATR.PR_N_V_PZ
from (select
ID_OBJ
from PEREGON where ID_STAN1=&arrival
)
inner join A_TOP on A_TOP.ID_OBJ=PRG.ID_OBJ and A_TOP.KODOP_P in ('03','07')
left join A_POEZD_ATR ATR on ATR.ID_POEZD=A_TOP.ID_POEZD and ATR.VRSVOP=A_TOP.VRSVOP
inner join (select
A_TOP.ID_POEZD
,A_TOP.vrsvop
from (select
distinct ID_OBJ_P as ID_OBJ
from TMO start with ID_OBJ=&dispatch
connect by prior ID_OBJ_P=ID_OBJ
) inner join A_TOP on A_TOP.ID_OBJ=STN_OBJ.ID_OBJ and A_TOP.KODOP_P in ('01','07')
left join A_POEZD_ATR ATR on ATR.ID_POEZD=A_TOP.ID_POEZD and ATR.VRSVOP=A_TOP.VRSVOP
WHERE ATR.NOM_POEZD LIKE '____') STN
on STN.ID_POEZD = ATR.ID_POEZD
WHERE ATR.NOM_POEZD LIKE '____';

Related

How to force returning multiple lines in SQL when there are duplicates inside "in" clause (Oracle)

My need may seems kind of odd but I need to extract a full column from an excel file and paste it inside a "IN" clause. In this column there are many duplicate values.
The SQL query would look like something like this :
SELECT pack.pack_lib,
upub.usr_nni,
upub.usr_email
FROM t_package pack
LEFT OUTER JOIN t_user upub ON upub.usr_id = pack.usr_id_publication
WHERE pack.pack_lib in(
'07655_23687_30863',
'07655_23687_30863',
'07432_76544_67890'
)
ORDER BY pack.date_publication DESC;
As you can see in this example, there are 2 duplicate values in the "IN" clause, and the standard behaviour of this query is to return a single value for these 2 values.
BUT I need to get two lines (which will be the same) and not a single one.
The above is just an example, but there wll be many values, some duplicates, and other not duplicates.
How to achieve this ? I work with ORACLE on version 9.2.0.8.0
In Oracle, you can INNER JOIN to a table collection expression:
SELECT pack.pack_lib,
upub.usr_nni,
upub.usr_email
FROM t_package pack
LEFT OUTER JOIN t_user upub
ON upub.usr_id = pack.usr_id_publication
INNER JOIN TABLE(SYS.ODCIVARCHAR2LIST(
'07655_23687_30863',
'07655_23687_30863',
'07432_76544_67890'
)) l
ON pack.pack_lib = l.COLUMN_VALUE
ORDER BY pack.date_publication DESC;
Which, for the sample data:
CREATE TABLE t_user(usr_id, usr_nni, usr_email) AS
SELECT 1, 1, 'alice#example.com' FROM DUAL UNION ALL
SELECT 2, 2, 'beryl#example.com' FROM DUAL;
CREATE TABLE t_package(usr_id_publication, pack_lib, date_publication) AS
SELECT 1, '07655_23687_30863', DATE '2022-01-01' FROM DUAL UNION ALL
SELECT 2, '07432_76544_67890', DATE '2022-01-02' FROM DUAL;
Outputs:
PACK_LIB
USR_NNI
USR_EMAIL
07432_76544_67890
2
beryl#example.com
07655_23687_30863
1
alice#example.com
07655_23687_30863
1
alice#example.com
If you do not have visibility of the SYS.ODCI*LIST types then you may be able to create a user-defined collection type:
CREATE TYPE string_list AS TABLE OF VARCHAR2(20);
then use:
SELECT pack.pack_lib,
upub.usr_nni,
upub.usr_email
FROM t_package pack
LEFT OUTER JOIN t_user upub
ON upub.usr_id = pack.usr_id_publication
INNER JOIN TABLE(string_list(
'07655_23687_30863',
'07655_23687_30863',
'07432_76544_67890'
)) l
ON pack.pack_lib = l.COLUMN_VALUE
ORDER BY pack.date_publication DESC;
db<>fiddle here
You need to use JOIN instead of semi-join (the IN syntax). The following query should work on Oracle:
SELECT pack.pack_lib,
upub.usr_nni,
upub.usr_email
FROM t_package pack
LEFT OUTER JOIN t_user upub ON upub.usr_id = pack.usr_id_publication
LEFT OUTER JOIN (
SELECT '07655_23687_30863' pack_lib FROM dual
UNION ALL
SELECT '07655_23687_30863' FROM dual
) t
ON pack.pack_lib = t.pack_lib;
SQL Server and PostgreSQL should allow also the following syntax
SELECT pack.pack_lib,
upub.usr_nni,
upub.usr_email
FROM t_package pack
LEFT OUTER JOIN t_user upub ON upub.usr_id = pack.usr_id_publication
LEFT OUTER JOIN (VALUES ('07655_23687_30863'), ('07655_23687_30863')) AS t(pack_lib)
ON pack.pack_lib = t.pack_lib;

LEFT JOIN & SUM GROUP BY

EDIT:
The result supposed to be like this:
desired result
I have this query:
SELECT DISTINCT mitarbeiter.mitarbnr, mitarbeiter.login, mitarbeiter.name1, mitarbeiter.name2
FROM vertragspos
left join vertrag_ek_vk_zuord ON vertragspos.id = vertrag_ek_vk_zuord.ek_vertragspos_id
left join mitarbeiter ON vertrag_ek_vk_zuord.anlage_mitarbnr = mitarbeiter.mitarbnr
left join vertragskopf ON vertragskopf.id = vertragspos.vertrag_id
left join
(
SELECT wkurse.*, fremdwaehrung.wsymbol
FROM wkurse
INNER join
(
SELECT lfdnr, Max(tag) AS maxTag
FROM wkurse
WHERE tag < SYSDATE
GROUP BY lfdnr
) t1
ON wkurse.lfdnr = t1.lfdnr AND wkurse.Tag = t1.maxTag
INNER JOIN fremdwaehrung ON wkurse.lfdnr = fremdwaehrung.lfdnr
) wkurse ON vertragskopf.blfdwaehrung = wkurse.lfdnr
left join
(
SELECT vertrag_ID, Sum (preis) preis, Sum (menge) menge, Sum (preis * menge / Decode (vertragskopf.zahlintervall, 1,1,2,2,3,3,4,6,5,12,1) / wkurse.kurs) vertragswert
FROM vertragspos
GROUP BY vertrag_ID
) s ON vertragskopf.id = s.vertrag_id
But I always get an error on line 21 Pos 145:
ORA-00904 WKURSE.KURS invalid identifier
The WKURSE table is supposed be joined already above, but why do I still get error?
How can I do join with all these tables?
I need to join all these tables:
Mitarbeiter, Vertragspos, vertrag_ek_vk_zuord, wkurse, fremdwaehrung, vertragskopf.
What is the right syntax? I'm using SQL Tool 1,8 b38
Thank you.
Because LEFT JOIN is executed on entire dataset, and not in row-by-row manner. So there's no wkurse.kurs available in the execution context of subquery. Since you join that tables, you can place the calculation in the top-most select statement.
EDIT:
After you edited the statement, it became clear where does vertragskopf.zahlintervall came from. But I don't know where are you going to use calculated vertragswert (now it is absent in the query), so I've put it in the result. As I'm not a SQL parser and have no idea of your tables, so I cannot check the code, but calculation now can be resolved (all the values are available in calculation context).
SELECT DISTINCT mitarbeiter.mitarbnr, mitarbeiter.login, mitarbeiter.name1, mitarbeiter.name2, s.amount / Decode (vertragskopf.zahlintervall, 1,1,2,2,3,3,4,6,5,12,1) / wkurse.kurs) vertragswert
FROM vertragspos
left join vertrag_ek_vk_zuord ON vertragspos.id = vertrag_ek_vk_zuord.ek_vertragspos_id
left join mitarbeiter ON vertrag_ek_vk_zuord.anlage_mitarbnr = mitarbeiter.mitarbnr
left join vertragskopf ON vertragskopf.id = vertragspos.vertrag_id
left join (
SELECT wkurse.*, fremdwaehrung.wsymbol
FROM wkurse
INNER join (
SELECT lfdnr, Max(tag) AS maxTag
FROM wkurse
WHERE tag < SYSDATE
GROUP BY lfdnr
) t1
ON wkurse.lfdnr = t1.lfdnr AND wkurse.Tag = t1.maxTag
INNER JOIN fremdwaehrung ON wkurse.lfdnr = fremdwaehrung.lfdnr
) wkurse ON vertragskopf.blfdwaehrung = wkurse.lfdnr
left join (
SELECT vertrag_ID, Sum (preis) preis, Sum (menge) menge, Sum (preis * menge) as amount
FROM vertragspos
GROUP BY vertrag_ID
) s ON vertragskopf.id = s.vertrag_id
Rewriting the code using WITH clause makes it much clearer than select from select.
Also get the rate on last day before today in oracle is as simple as
select wkurse.lfdnr
, max(wkurse.kurs) keep (dense_rank first order by wkurse.tag desc) as rate
from wkurse
where tag < sysdate
group by wkurse.lfdnr
One option is a lateral join:
left join lateral
(SELECT vertrag_ID, Sum(preis) as preis, Sum(menge) as menge,
Sum (preis * menge / Decode (vertragskopf.zahlintervall, 1,1,2,2,3,3,4,6,5,12,1) / wkurse.kurs) vertragswert
FROM vertragspos
GROUP BY vertrag_ID
) s
ON vertragskopf.id = s.vertrag_id

Syntax error in sql Query Design

I have design one query such as
Select Temp3.*
From (
(Select temp1.alletec_ce1name,temp1.employeeid, count (temp1.alletec_mifid) AS MifAssign,alletec_mifid
from (select MIF.alletec_ce1name,User1.employeeid,MIF.alletec_mifid from Filteredalletec_mif as MIF FULL OUTER JOIN FilteredSystemUser As User1 on MIF.alletec_ce1=User1.systemuserid
FULL OUTER JOIN FilteredBusinessUnit as BU ON User1.businessunitid=BU.businessunitid
where MIF.alletec_organisationname='Konica Minolta India' AND MIF.alletec_cityname ='Delhi' AND
MIF.alletec_regionname ='North' ) as temp1
Group by temp1.alletec_mifid,temp1.alletec_ce1name,temp1.employeeid ) as Temp2 Inner Join FilteredIncident As Incident On Incident.alletec_serialnomif=Temp2.alletec_mifid ) as temp3
Now the issue is it is showing the Syntax error near the first from. What can be the possible reason for that. Thanks in advance.
I have one more query, such as
with temp2 (
alletec_ce1name,
employeeid,
alletec_mifid,
alletec_cityname,
alletec_regionname
)
as(
Select temp1.alletec_ce1name,temp1.employeeid, temp1.alletec_mifid, temp1.alletec_cityname,temp1.alletec_regionname
from (select MIF.alletec_ce1name,User1.employeeid,MIF.alletec_mifid, MIF.alletec_regionname, MIF.alletec_cityname from Filteredalletec_mif as MIF FULL OUTER JOIN FilteredSystemUser As User1 on MIF.alletec_ce1=User1.systemuserid
FULL OUTER JOIN FilteredBusinessUnit as BU ON User1.businessunitid=BU.businessunitid
where MIF.alletec_organisationname='Konica Minolta India' AND (MIF.alletec_cityname ='Delhi') AND
(MIF.alletec_regionname ='North') ) as temp1
)
select temp2.alletec_ce1name,temp2.employeeid, temp2.alletec_regionname,temp2.alletec_cityname, count(alletec_mifid) as MIFASSIGN,
Incident.alletec_casecalltypename
from temp2 Left Outer join FilteredIncident As Incident On Incident.alletec_serialnomif=temp2.alletec_mifid
group by temp2.alletec_ce1name,temp2.employeeid,temp2.alletec_mifid,temp2.alletec_regionname,temp2.alletec_cityname,
Incident.alletec_casecalltypename
now as with i got one temporary table. i wish to have one more temporary table so that can incorporate my last executable table values from temp2. do have a look if u can help for either. Thanks
Count up your parentheses, I think they are mismatched.
Your query amounts to
select
*
from
(table) as temp3
This isn't valid, you can't put the parentheses there. The extra level of nesting is broken. You either need to do something like:
select
*
from
table
or something like
select
*
from (
select
*
from
table
) as temp3
Your first query can probably be simplified to:
Select
*
From (
select
MIF.alletec_ce1name,
User1.employeeid,
MIF.alletec_mifid,
count (MIF.alltec_mifid) as MifAssign
from
Filteredalletec_mif as MIF
full outer join
FilteredSystemUser As User1
on MIF.alletec_ce1 = User1.systemuserid
full outer join
FilteredBusinessUnit as BU
on User1.businessunitid=BU.businessunitid
where
MIF.alletec_organisationname = 'Konica Minolta India' AND
MIF.alletec_cityname ='Delhi' AND
MIF.alletec_regionname ='North'
group by
MIF.alletec_mifid,
MIF.alletec_ce1name,
User1.employeeid
) as temp1
Inner Join
FilteredIncident As Incident
On Incident.alletec_serialnomif = Temp1.alletec_mifid;

SQL Query- Table as invalid object

I have a SQL query
Select
temp1.domainname,
temp1.employeeid,
temp1.alletec_plantcode,
temp1.name,
temp1.alletec_customerengineer1name,
temp1.alletec_cityname,
temp1.alletec_regionname,
temp1.alletec_ce1name,
temp1.alletec_casecalltypename,
count(temp1.alletec_ce1name) as TOTALMIFASSIGN ,
(select count( MIF.alletec_ce1name) from temp1 where temp1.alletec_casecalltypename='aa') as CMMIFASSIGN
from (
Select
User1.domainname,
User1.employeeid,
User1.alletec_plantcode,
BU.name,
MIF.alletec_customerengineer1name,
MIF.alletec_cityname,
MIF.alletec_regionname,
MIF.alletec_ce1name,
Incident.alletec_casecalltypename
From
FilteredSystemUser As User1 Inner Join FilteredBusinessUnit As BU ON User1.businessunitid=BU.businessunitid
Inner join Filteredalletec_mif As MIF ON MIF.alletec_ce1=User1.systemuserid
Inner join FilteredIncident As Incident On Incident.alletec_serialnomif=MIF.alletec_mifid
where MIF.alletec_ce1name='Amit Chauhan' AND MIF.alletec_cityname='Gurgaon' and MIF.alletec_regionname='North' and Incident.statecodename='Resolved'
group by User1.domainname,
User1.employeeid,
User1.alletec_plantcode,
BU.name,
MIF.alletec_cityname,
MIF.alletec_regionname,
MIF.alletec_ce1name,
MIF.alletec_customerengineer1name,
Incident.alletec_casecalltypename
) As temp1
group by
temp1.domainname,
temp1.employeeid,
temp1.alletec_plantcode,
temp1.name,
temp1.alletec_customerengineer1name,
temp1.alletec_cityname,
temp1.alletec_regionname,
temp1.alletec_ce1name,
temp1.alletec_casecalltypename
The particular query above showing the temp1 as Invalid Object in the count query as i am require to place further filtration on it. Cant we use the above query in Aggregate function. Kindly suggest the an alternative to it.
Thanks.
The problem seem to be that the table alias temp1 isn't available when the query processor tries to resolve it. One solution that should work would be to wrap the query in a common table expression (cte). I believe this will work.
Try this:
;with temp1 (
domainname, employeeid,
alletec_plantcode, name,
alletec_customerengineer1name,
alletec_cityname, alletec_regionname,
alletec_ce1name, alletec_casecalltypename
)
as (
Select
User1.domainname,
User1.employeeid,
User1.alletec_plantcode,
BU.name,
MIF.alletec_customerengineer1name,
MIF.alletec_cityname,
MIF.alletec_regionname,
MIF.alletec_ce1name,
Incident.alletec_casecalltypename
From
FilteredSystemUser As User1 Inner Join FilteredBusinessUnit As BU ON User1.businessunitid=BU.businessunitid
Inner join Filteredalletec_mif As MIF ON MIF.alletec_ce1=User1.systemuserid
Inner join FilteredIncident As Incident On Incident.alletec_serialnomif=MIF.alletec_mifid
where MIF.alletec_ce1name='Amit Chauhan' AND MIF.alletec_cityname='Gurgaon' and MIF.alletec_regionname='North' and Incident.statecodename='Resolved'
group by User1.domainname,
User1.employeeid,
User1.alletec_plantcode,
BU.name,
MIF.alletec_cityname,
MIF.alletec_regionname,
MIF.alletec_ce1name,
MIF.alletec_customerengineer1name,
Incident.alletec_casecalltypename
)
Select
temp1.domainname,
temp1.employeeid,
temp1.alletec_plantcode,
temp1.name,
temp1.alletec_customerengineer1name,
temp1.alletec_cityname,
temp1.alletec_regionname,
temp1.alletec_ce1name,
temp1.alletec_casecalltypename,
(select count(temp1.alletec_ce1name) from temp1) as TOTALMIFASSIGN
from temp1

How to write this SQL statement correctly?

As written in the title: How to write this SQL statement correctly?
select
sl.switch_ip,
sl.switch_name,
count(m.switch_ip) as macentries,
(select arpentries from (select sl1.switch_ip, sl1.switch_name, count(ar.switch_ip) as arpentries
from my_switchlist sl1
left Join my_arptable ar on ar.switch_ip = sl1.switch_ip
group by sl1.switch_ip,sl1.switch_name
order by sl1.switch_ip))
from my_switchlist sl
left Join my_mactable m on m.switch_ip = sl.switch_ip
group by sl.switch_ip,sl.switch_name
order by sl.switch_ip
The select and the sub-select work fine if they are executed separately.
But as soon as I put them together I get the following error:
Error: A subquery has returned not exactly one row.
SQLState: 21000
ErrorCode: -284
Position: 470
Looks like you want both the 'count' aggregates, which should be possible with something like this:
select
macquery.switch_ip,
macquery.switch_name,
macquery.macentries,
arpquery.arpentries
from
(
select
sl.switch_ip as switch_ip,
sl.switch_name as switch_name,
count(m.switch_ip) as macentries
from my_switchlist sl
left outer join my_mactable m
on m.switch_ip = sl.switch_ip
group by
sl.switch_ip,
sl.switch_name
) macquery
join
(
select
sl1.switch_ip as switch_ip,
sl1.switch_name as switch_name,
count(ar.switch_ip) as arpentries
from my_switchlist sl1
left outer join my_arptable ar
on ar.switch_ip = sl1.switch_ip
group by
sl1.switch_ip,
sl1.switch_name
) arpquery
on (macquery.switch_ip = arpquery.switch_ip
and macquery.switch_name = arpquery.switch_name)
Probably there are more than one "sl1.switch_ip,sl1.switch_name" groups in your "my_switchlist, my_arptable" join.
select arpentries from (select sl1.switch_ip, sl1.switch_name, count(ar.switch_ip) as arpentries
from my_switchlist sl1
left Join my_arptable ar on ar.switch_ip = sl1.switch_ip
group by sl1.switch_ip,sl1.switch_name
order by sl1.switch_ip)
The above query should not return more than one result in order you to use its result in your outer query. So probably there is more than one "sl1.switch_ip,sl1.switch_name" group.