oracle ora-00979 symfony2 doctrine2 - sql

I'm building the following DQL:
SELECT partial operador.{id, pmn, neteo},
sum(outcollect.montoTotal) as montoOut,
outcollect.periodo as periodo,
outcollect.pagado
FROM RoamingOperadoresBundle:Operador operador
LEFT JOIN operador.operadorHub operadorHub
LEFT JOIN operador.outcollect outcollect
WHERE operador.ishub = 0
AND operador.neteo = 1
AND operador.incluirReportes = 1
AND operador.pmn not in('CHLTM', 'CHLCM')
AND operador.id not in(SELECT op.id
FROM RoamingOperadoresBundle:Operador op
LEFT JOIN op.operadorHub opHub
LEFT JOIN op.outcollect out
WHERE (opHub.desde <= out.periodo and (opHub.hasta >= out.periodo or opHub.hasta is null))
)
AND operador.activo = 1
GROUP BY operador.pmn, outcollect.periodo ORDER BY operador.pmn
Which transforms into this SQL:
SELECT o0_.id AS ID0,
o0_.pmn AS PMN1,
o0_.neteo AS NETEO2,
sum(o1_.monto_total) AS SCLR3,
o1_.periodo AS PERIODO4,
o1_.pagado AS PAGADO5
FROM operador o0_
LEFT JOIN operador_hub o2_ ON o0_.id = o2_.operador_id
LEFT JOIN outcollect o1_ ON o0_.id = o1_.operador_id
WHERE o0_.ishub = 0
AND o0_.neteo = 1
AND o0_.incluirReportes = 1
AND o0_.pmn NOT IN ('CHLTM', 'CHLCM')
AND o0_.id NOT IN (SELECT o3_.id FROM operador o3_ LEFT JOIN operador_hub o4_ ON o3_.id = o4_.operador_id LEFT JOIN outcollect o5_ ON o3_.id = o5_.operador_id WHERE (o4_.desde <= o5_.periodo AND (o4_.hasta >= o5_.periodo OR o4_.hasta IS NULL)))
AND o0_.activo = 1
GROUP BY o0_.pmn, o1_.periodo
ORDER BY o0_.pmn ASC
Which gives the following error:
ORA-00979: no es una expresión GROUP BY
Any pointers on how to change the DQL to solve this problem?
I'm using doctrine2, symfony2 and OCI8

Per Oracle documentation
ORA-00979 not a GROUP BY expression
Cause: The GROUP BY clause does not contain all the expressions in the SELECT clause. SELECT expressions that are not included in a group
function, such as AVG, COUNT, MAX, MIN, SUM, STDDEV, or VARIANCE, must
be listed in the GROUP BY clause.
Action: Include in the GROUP BY clause all SELECT expressions that
are not group function arguments.
So you need to include all the expressions/column in select list to your group by. change the group by of your SQL query to below
group by o0_.pmn, o1_.periodo, o0_.neteo, o1_.pagado, o0_.id
GROUP BY of DQL to
GROUP BY operador.pmn, outcollect.periodo, operador.id,
operador.neteo, outcollect.pagado

Related

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

Subquery SQL DB2

I am trying to create a subquery (for a particular column) inside my base query. the code is as follows.
SELECT z.po_id,
max
(
select etcdc.ship_evnt_tms
FROM covinfos.shipment_event etcdc
WHERE etcdc.ship_evnt_cd = '9P'
AND etcdc.ship_id=scdc.ship_id
ORDER BY etcdc.updt_job_tms desc
FETCH first ROW only) AS llp_estimated_delivery_cdc
FROM covinfos.ibm_plant_order z
LEFT JOIN covinfos.ipo_line_to_case a
ON z.po_id = a.po_id
LEFT JOIN covinfos.shipment scdc
ON (
a.ship_id = scdc.ship_id
AND a.ship_to_loc_code = scdc.ship_to_loc_code
AND scdc.loc_type = 'CDC')
GROUP BY z.po_id
There seems to be some kind of typo somewhere based on the error message that pops up when I try to run the code.
BIC00004. DAL01008. An error occurred while accessing the database.
ILLEGAL SYMBOL ".". SOME SYMBOLS THAT MIGHT BE LEGAL ARE: , ). SQLCODE=-104,
SQLSTATE=42601, DRIVER=3.62.56; THE CURSOR SQL_CURLH200C1 IS NOT IN A
PREPARED STATE. SQLCODE=-514, SQLSTATE=26501, DRIVER=3.62.56
However, at plain sight or at least my sight, there is nothing that spots the misstake. Furthermore, running the subselect in a blank sheet (outside the base query, new one) it does correctly.
Thanks
You would probably be best to remove the co-related sub-select, and just join to a plain sub-select. E.g.
SELECT z.po_id,
max(ship_evnt_tms) AS llp_estimated_delivery_cdc
FROM covinfos.ibm_plant_order z
LEFT JOIN covinfos.ipo_line_to_case a
ON z.po_id = a.po_id
LEFT JOIN covinfos.shipment scdc
ON a.ship_id = scdc.ship_id
AND a.ship_to_loc_code = scdc.ship_to_loc_code
AND scdc.loc_type = 'CDC'
LEFT JOIN
( select ship_id
, ship_evnt_tms
FROM
( select ship_id
, ship_evnt_tms
, row_number() over(partition by ship_id order by updt_job_tms desc) as RN
FROM covinfos.shipment_event
WHERE ship_evnt_cd = '9P'
) s
WHERE RN = 1
) AS etcdc
ON etcdc.ship_id=scdc.ship_id
GROUP BY z.po_id
P.S. you could just INNER JOINs unless you want to include po_id's with no ship_evnt_tms
Try adding parentheses around the sub-select. At least this then parses Data Studio using z/OS validation
SELECT z.po_id,
max
((
select etcdc.ship_evnt_tms
FROM covinfos.shipment_event etcdc
WHERE etcdc.ship_evnt_cd = '9P'
AND etcdc.ship_id=scdc.ship_id
ORDER BY etcdc.updt_job_tms desc
FETCH first ROW only)) AS llp_estimated_delivery_cdc
FROM covinfos.ibm_plant_order z
LEFT JOIN covinfos.ipo_line_to_case a
ON z.po_id = a.po_id
LEFT JOIN covinfos.shipment scdc
ON (
a.ship_id = scdc.ship_id
AND a.ship_to_loc_code = scdc.ship_to_loc_code
AND scdc.loc_type = 'CDC')
GROUP BY z.po_id
Still, I'm not sure this is a very nice bit of SQL code.

oracle ora-00904 with symfony2 and doctrine2

I have a doctrine DQL that transforms into this SQL:
SELECT o0_.id AS ID0,
o0_.pmn AS PMN1,
o0_.neteo AS NETEO2,
sum(o1_.monto_total) AS SCLR3,
o1_.periodo AS PERIODO4,
o1_.pagado AS PAGADO5
FROM operador o0_
LEFT JOIN operador_hub o2_ ON o0_.id = o2_.operador_id
LEFT JOIN outcollect o1_ ON o0_.id = o1_.operador_id
WHERE o0_.ishub = 0
AND o0_.neteo = 1
AND o0_.incluirReportes = 1
AND o0_.pmn NOT IN ('CHLTM', 'CHLCM')
AND o0_.id NOT IN (SELECT o3_.id FROM operador o3_ LEFT JOIN operador_hub o4_ ON o3_.id = o4_.operador_id LEFT JOIN outcollect o5_ ON o3_.id = o5_.operador_id WHERE (o4_.desde <= o5_.periodo AND (o4_.hasta >= o5_.periodo OR o4_.hasta IS NULL)))
AND o0_.activo = 1
GROUP BY o0_.pmn, PERIODO4
ORDER BY o0_.pmn ASC
this gives an ORA-00904: "PERIODO4": identificador no válido
the error is directly related to the GROUP BY o0_.pmn, PERIODO4 line
It seems related to doctrine that cannot translate the query to an ORACLE syntax. I'm using OCI8 driver.
Any thoughts?
---- edit ----
here is the DQL:
SELECT partial operador.{id, pmn, neteo},
sum(outcollect.montoTotal) as montoOut,
outcollect.periodo as periodo,
outcollect.pagado as pagado
FROM RoamingOperadoresBundle:Operador operador
LEFT JOIN operador.operadorHub operadorHub
LEFT JOIN operador.outcollect outcollect
WHERE operador.ishub = 0
AND operador.neteo = 1
AND operador.incluirReportes = 1
AND operador.pmn not in('CHLTM', 'CHLCM')
AND operador.id not in(SELECT op.id
FROM RoamingOperadoresBundle:Operador op
LEFT JOIN op.operadorHub opHub
LEFT JOIN op.outcollect out
WHERE (opHub.desde <= out.periodo and (opHub.hasta >= out.periodo or opHub.hasta is null)))
AND operador.activo = 1
GROUP BY operador.pmn, periodo ORDER BY operador.pmn
I'm not sure how you are generating this table expression, but you are getting the error because you aren't including all non-aggregated columns in the GROUP BY clause.
Also note - you can't group by an alias. You must refer to the column by specifying it in table.column form.
It should look like this:
GROUP BY o0_.pmn, o0_.neteo, o1_.periodo, o1_.pagado

Rails: SQL SELECT Statement Not Appearing When Combined With GROUP BY

I have the following code in Ruby:
Comment.select("comments.*, COALESCE(SUM(votes.value), 0) AS rating,
user_votes.value AS user_value").
joins("LEFT JOIN votes ON votes.voteable_type = '"+type+"' AND votes.voteable_id = comments.id").
joins("LEFT JOIN votes AS user_votes ON user_votes.voteable_type = '"+type+"' AND user_votes.voteable_id = comments.id AND user_votes.user_id = #{user_id}").
where(conditions).group("comments.id").order("comments."+method).limit(limit).offset(offset)
When Rails generates this SQL query, it doesn't include the full select statement:
SELECT COUNT(*) AS count_all, comments.id AS comments_id FROM `comments`
LEFT JOIN votes ON votes.voteable_type = 'reply' AND votes.voteable_id = comments.id
LEFT JOIN votes AS user_votes ON user_votes.voteable_type = 'reply' AND
user_votes.voteable_id = comments.id AND user_votes.user_id = 1 WHERE (commentable_id =
1 AND commentable_type = 'Impression')
GROUP BY comments.id ORDER BY comments.rating DESC LIMIT 10 OFFSET 0
If I remove the group statement, however, then it properly includes the full select statement. What's going on?
select comments.* in your select statement conflicts with group by("comments.id").
Every column selected must either be in the GROUP BY clause or be contained in an aggregate function.
SQL Server shows error for SQL:
select c.* from tt_country c group by c.name
Column 'tt_country.country_id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
ActiveRecord and arel throws out the specified select because it is ambiguous / invalid.

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.