Access nested select in field listing - sql

I have been provided a query to search for some data in the db that looks like this:
select nvl(to_char(a.empresa), 'SEM REMESSA') empresa,
c.conta,
nvl(sum(a.valor_total), 0) as folha,
(select count(distinct(l2.creditado))
from lancamentos l2
inner join vw_arquivos a2
on l2.arquivo = a2.arquivo
where a2.empresa = a.empresa) as funcionarios
from conta_table c
left join vw_arquivos a
on c.conta = a.conta
and a.situacao = 6
group by a.empresa, c.conta
I have to get the value of the operation folha / funcionarios, but if I put this in the field listing I get the error:
ORA-00904: "FUNCIONARIOS": invalid identifier
00904. 00000 - "%s: invalid identifier"
And when I replace my reference to funcionarios with the same nested select, I get the same error on reference folha.
I know I could just replace both references with their respective calculations, and it works. Like this:
nvl(sum(a.valor_total), 0) /
(select count(distinct(l2.creditado))
from lancamentos l2
inner join vw_arquivos a2
on l2.arquivo = a2.arquivo
where a2.empresa = a.empresa) as division
But this looks not so optimized and not like the best way to do it. So my question is...
Is there any way to select these values with this last division operation, but more optimized than repeating the folha and funcionarios calculations? Maybe a way to reference these already calculated values.

folha and funcionarios cannot be referenced in the same query because they are aliases. You have to make the entire query as subquery, and get the division, like so:
select empresa, conta, folha/funcionarios folha_div_funcionarios
from (
select nvl(to_char(a.empresa), 'SEM REMESSA') empresa,
c.conta,
nvl(sum(a.valor_total), 0) as folha,
(select count(distinct(l2.creditado))
from lancamentos l2
inner join vw_arquivos a2
on l2.arquivo = a2.arquivo
where a2.empresa = a.empresa) as funcionarios
from conta_table c
left join vw_arquivos a
on c.conta = a.conta
and a.situacao = 6
group by a.empresa, c.conta
)

Related

Cannot enclose a query with an outer query in Firebird 2.5

My inner query is returning results but I get this error
SQL Error [336397221] [42000]: Dynamic SQL Error; SQL error code =
-104; Invalid command; column NOME was specified multiple times for derived table EX [SQLState:42000, ISC error code:336397221]
Here is my query
select * from ( --this gives error
SELECT t.placa, m.nome, GA.ID_AUDESP, GA.NOME AS GRUPO_AUDESP,
T.VALOR as valor,
T.DT_AQUISICAO,
PS.NOME
FROM PATRIMONIO_TOMBAMENTO T
LEFT JOIN PATRIMONIO_GRUPO_AUDESP GA ON GA.ID_GRUPO_AUDESP = T.ID_GRUPO_AUDESP
LEFT JOIN ESTOQUE_MATERIAL M ON M.ID_MATERIAL = T.ID_MATERIAL
LEFT JOIN PATRIMONIO_SETOR PS ON (T.ID_SETOR = PS.ID_SETOR)
WHERE T.ID_ORGAO = '030000'
AND (T.SITUACAO IN('A') or ( T.SITUACAO = 'B' AND T.DT_BAIXA >'2022-01-31'))
AND (T.DT_REATIVADO IS NULL OR T.DT_REATIVADO<= '2022-01-31' or (T.DT_BAIXA >'2022-01-31'))
AND T.dt_cadastro <= '2022-01-31'
) ex
Your derived table has two columns with the name/alias NOME (m.nome and PS.NOME), and as the error indicates, this is not allowed as a name should occur only once. You need to alias one or both columns so they have unique names, or exclude one of them if it would have the same value. The same was already done for the third occurrence of NOME, GA.NOME.
For example:
select * from (
SELECT t.placa,
m.nome as m_nome,
GA.ID_AUDESP,
GA.NOME AS GRUPO_AUDESP,
T.VALOR as valor,
T.DT_AQUISICAO,
PS.NOME as ps_nome
FROM PATRIMONIO_TOMBAMENTO T
-- ...

Case When + IN combination

I'm a bit stuck in my coding here... I have this extense and complex code, but I'm actually failling by the end of it. I'm getting the SQL Error [42804]: ERROR: argument of CASE/WHEN must be type boolean, not type character varying
The thing, is: when "bairro" matches a row from "SUB_COUNTRY_DB", get psd.name, else get z.name. Any tips on how I could accomplish this?
select distinct
aa.mes,
--aa.modalidade,
--to_date(aa.created_date, 'yyyy-mm-dd') data_captacao,
ucl.ja_comprou_lf as comprou_lf,
case when bairro in (select sub_country from sub_country_DB)
then psd.name
else z.name
end loja,
count (distinct aa.customer_uid) qtde_socios,
count (distinct aa.assinatura_uid) qtde_assinaturas
from assinaturas_ativas aa
left join ultima_compra_loja_fisica ucl on (aa.customer_uid = ucl.customer_uid
and aa.mes = ucl.mes)
left join zip_code z on (aa.customer_uid = z.customer_uid
and aa.mes = z.mes)
left join SUB_COUNTRY_DB psd
on (psd.district = aa.bairro)
group by 1,2,3--,4
Try variants like:
moving condition to an inner query
CASE WHEN EXISTS (SELECT DISTINCT sub_country FROM sub_country_DB WHERE sub_country = barrio)
ANY (PostgreSQL only)
CASE WHEN bairro = ANY(ARRAY_AGG(select sub_country from sub_country_DB))

SQL problems duplicate column name using inner join and missing right parenthesis

SELECT
BillNo, Non_resident,
SUM(ConsumptionCharge AND SupplyCharge) AS "TotalCharge"
FROM
BILL
INNER JOIN
ACCOUNT ON ACCOUNT.BILLNO = BILL.BILLNO
WHERE
Non_resident = Upper('Yes') AND to_char(CreatedDate,'mm') = '09'
GROUP BY
ACCOUNT.BILLNO;
CREATE OR REPLACE VIEW View_B
AS
SELECT DISTINCT*
FROM BILL
INNER JOIN
(SELECT DISTINCT * FROM METER) M ON M.BillNo = BILL.BillNo
JOIN
(SELECT DISTINCT * FROM SERVICEADDRESS) SA ON M.AddressID = SA.AddressID
WHERE
SA.PostCode = '1267'
AND SA.FullAddress = '53 Drip Drive, Dripwater'
AND CreatedDate BETWEEN to_date('2020-01','yyyy-mm') AND to_date('2020-09','yyyy-mm');
The first select does not work at all, showing error
ORA-00907: missing right parenthesis
The second one does work, but it have duplicate column name. Those distinct does seems to be working somehow and I have to use inner join.
enter image description here
For the first query, the GROUP BY is inconsistent with the SELECT. Plus, the SUM() expression is not correct:
SELECT ACCOUNT.BillNo, UPPER(Non_resident) as Non_resident,
SUM(ConsumptionCharge + SupplyCharge) AS TotalCharge
FROM BILL JOIN
ACCOUNT
ON ACCOUNT.BILLNO = BILL.BILLNO
WHERE Non_resident = Upper('Yes') AND to_char(CreatedDate,'mm') = '09'
GROUP BY ACCOUNT.BILLNO;

ORA-00904 Invalid Identifier Error Teradata

I'm having trouble identifying the error in my code that occurred once I added an aggregate function to it. Each of the submitterclaimnumber items have multiple rows each with increasing values under the seqnumber column.
I'm trying to pull the row that has the highest seqnumber for each particular submitterclaimnumber.
For example. I have a submitterclaimnumber 999 with multiple rows. Each row is distinguished by a different value under seqnumber
so I have:
submitterclaimnumber = 999 seqnumber = 1
submitterclaimnumber = 999 seqnumber = 2
submitterclaimnumber = 999 seqnumber = 3
I only want the submitterclaimnumber = 999 seqnumber = 3 to show.
I can provide a bit more info on how the table is set up if needed.
The error I'm getting is:
"SELECT Failed. 904: ORA-00904: "MAX_SEQ": invalid identifier"
SELECT
CR.CLAIMNUMBER
,CR.LINENUMBER
,SUBSTR(CLM.SUBMITTERCLAIMNUMBER,3,11) AS CLM_NBR
,CR.SEQNUMBER
,MAX(CR.SEQNUMBER) AS MAX_SEQ
,CR.VOLUME
,CR.VOLUMETYPE
,CR.RATE
,CR.RATETYPE
,CR.ALLOWED
FROM PRICER.CLMREPRICINGDETAIL CR
INNER JOIN PRICER.CLMCLAIMS CLM
ON CLM.CLAIMNUMBER = CR.CLAIMNUMBER
INNER JOIN PRICER.CLMCLAIMITEMS CLMP
ON CLM.CLAIMNUMBER = CLMP.CLAIMNUMBER
AND CLM.OWNERID = CLMP.OWNERID
INNER JOIN PRICER.CLMINSURED CLMI
ON CLM.CLAIMNUMBER = CLMI.CLAIMNUMBER
AND CLM.OWNERID = CLMI.OWNERID
WHERE
TRADEPARTNERID IN ('NationalNonHouse','NationalHouse')
AND SUBSTR(CLM.SUBMITTERCLAIMNUMBER,3,11) IN ('17304CD2083','17297CA4107')
GROUP BY 1,2,3,4,5,6,7,8,9,10
HAVING CR.SEQNUMBER = MAX_SEQ
;
You might be using Teradata's SQL Assistant to query your Oracle system, but you're not using it against a Teradata DBMS :-)
To get the row with the max SEQNUMBER per SUBMITTERCLAIMNUMBER you can't use HAVING, because after aggregation there's no more individual row to compare to. But Windowed Aggregate allow that:
SELECT *
FROM
(
SELECT
CR.CLAIMNUMBER
,CR.LINENUMBER
,SUBSTR(CLM.SUBMITTERCLAIMNUMBER,3,11) AS CLM_NBR
,CR.SEQNUMBER
,MAX(CR.SEQNUMBER) OVER (PARTITON BY SUBMITTERCLAIMNUMBER) AS MAX_SEQ
,CR.VOLUME
,CR.VOLUMETYPE
,CR.RATE
,CR.RATETYPE
,CR.ALLOWED
FROM PRICER.CLMREPRICINGDETAIL CR
INNER JOIN PRICER.CLMCLAIMS CLM
ON CLM.CLAIMNUMBER = CR.CLAIMNUMBER
INNER JOIN PRICER.CLMCLAIMITEMS CLMP
ON CLM.CLAIMNUMBER = CLMP.CLAIMNUMBER
AND CLM.OWNERID = CLMP.OWNERID
INNER JOIN PRICER.CLMINSURED CLMI
ON CLM.CLAIMNUMBER = CLMI.CLAIMNUMBER
AND CLM.OWNERID = CLMI.OWNERID
WHERE
TRADEPARTNERID IN ('NationalNonHouse','NationalHouse')
AND SUBSTR(CLM.SUBMITTERCLAIMNUMBER,3,11) IN ('17304CD2083','17297CA4107')
-- no more GROUP BY
) dt
WHERE SEQNUMBER = MAX_SEQ
;
Btw, in Teradata SQL you could remove the Derived Table and simply use QUALIFY. Then it looks quite close to your original syntax:
QUALIFY
CR.SEQNUMBER
= MAX(CR.SEQNUMBER) OVER (PARTITON BY CLM.SUBMITTERCLAIMNUMBER)
You can't use alias inside a query, you have to use the MAX(CR.SEQNUMBER) in your HAVING clause
you can't compare a not aggregate row like CR.SEQNUMBER inside a HAVING
:
SELECT
CR.CLAIMNUMBER
,CR.LINENUMBER
,SUBSTR(CLM.SUBMITTERCLAIMNUMBER,3,11) AS CLM_NBR
,CR.SEQNUMBER
,MAX(CR.SEQNUMBER) AS MAX_SEQ
,CR.VOLUME
,CR.VOLUMETYPE
,CR.RATE
,CR.RATETYPE
,CR.ALLOWED
FROM PRICER.CLMREPRICINGDETAIL CR
INNER JOIN PRICER.CLMCLAIMS CLM
ON CLM.CLAIMNUMBER = CR.CLAIMNUMBER
INNER JOIN PRICER.CLMCLAIMITEMS CLMP
ON CLM.CLAIMNUMBER = CLMP.CLAIMNUMBER
AND CLM.OWNERID = CLMP.OWNERID
INNER JOIN PRICER.CLMINSURED CLMI
ON CLM.CLAIMNUMBER = CLMI.CLAIMNUMBER
AND CLM.OWNERID = CLMI.OWNERID
WHERE
TRADEPARTNERID IN ('NationalNonHouse','NationalHouse')
AND SUBSTR(CLM.SUBMITTERCLAIMNUMBER,3,11) IN ('17304CD2083','17297CA4107')
GROUP BY
CR.CLAIMNUMBER
,CR.LINENUMBER
,SUBSTR(CLM.SUBMITTERCLAIMNUMBER,3,11)
,CR.SEQNUMBER
,CR.VOLUME
,CR.VOLUMETYPE
,CR.RATE
,CR.RATETYPE
,CR.ALLOWED
-- HAVING CR.SEQNUMBER = MAX(CR.SEQNUMBER) -- not allowed
;

Column is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause

Ok here's my View (vw_LiftEquip)
SELECT dbo.tbl_equip_swl_unit.unit_id,
dbo.tbl_equip_swl_unit.unit_name,
dbo.tbl_equip_swl_unit.archived,
dbo.tbl_categories.category_id,
dbo.tbl_categories.categoryName,
dbo.tbl_categories.parentCategory,
dbo.tbl_categories.sub_category,
dbo.tbl_categories.desc_category,
dbo.tbl_categories.description,
dbo.tbl_categories.miscellaneous,
dbo.tbl_categories.category_archived,
dbo.tbl_equip_swl_unit.unit_name AS Expr1,
dbo.tbl_categories.categoryName AS Expr2,
dbo.tbl_categories.description AS Expr3,
dbo.tbl_equip_depts.dept_name,
dbo.tbl_equip_man.man_name,
dbo.tbl_Lifting_Gear.e_defects AS Expr7,
dbo.tbl_Lifting_Gear.e_defects_desc AS Expr8,
dbo.tbl_Lifting_Gear.e_defects_date AS Expr9,
dbo.tbl_equipment.equipment_id,
dbo.tbl_equipment.e_contract_no,
dbo.tbl_equipment.slID,
dbo.tbl_equipment.e_entered_by,
dbo.tbl_equipment.e_serial,
dbo.tbl_equipment.e_model,
dbo.tbl_equipment.e_description,
dbo.tbl_equipment.e_location_id,
dbo.tbl_equipment.e_owner_id,
dbo.tbl_equipment.e_department_id,
dbo.tbl_equipment.e_manafacture_id,
dbo.tbl_equipment.e_manDate1,
dbo.tbl_equipment.e_manDate2,
dbo.tbl_equipment.e_manDate3,
dbo.tbl_equipment.e_dimensions,
dbo.tbl_equipment.e_test_no,
dbo.tbl_equipment.e_firstDate1,
dbo.tbl_equipment.e_firstDate2,
dbo.tbl_equipment.e_firstDate3,
dbo.tbl_equipment.e_prevDate1,
dbo.tbl_equipment.e_prevDate2,
dbo.tbl_equipment.e_prevDate3,
dbo.tbl_equipment.e_insp_frequency,
dbo.tbl_equipment.e_swl,
dbo.tbl_equipment.e_swl_unit_id,
dbo.tbl_equipment.e_swl_notes,
dbo.tbl_equipment.e_cat_id,
dbo.tbl_equipment.e_sub_id,
dbo.tbl_equipment.e_parent_id,
dbo.tbl_equipment.e_last_inspector,
dbo.tbl_equipment.e_last_company,
dbo.tbl_equipment.e_deleted AS Expr11,
dbo.tbl_equipment.e_deleted_desc AS Expr12,
dbo.tbl_equipment.e_deleted_date AS Expr13,
dbo.tbl_equipment.e_deleted_insp AS Expr14,
dbo.tbl_Lifting_Gear.e_defects_action AS Expr15,
dbo.tbl_equipment.e_rig_location,
dbo.tbl_Lifting_Gear.e_add_type AS Expr17,
dbo.tbl_Lifting_Gear.con_id,
dbo.tbl_Lifting_Gear.lifting_date,
dbo.tbl_Lifting_Gear.lifting_ref_no,
dbo.tbl_Lifting_Gear.e_id,
dbo.tbl_Lifting_Gear.inspector_id,
dbo.tbl_Lifting_Gear.lift_testCert,
dbo.tbl_Lifting_Gear.lift_rig_location,
dbo.tbl_Lifting_Gear.inspected,
dbo.tbl_Lifting_Gear.lifting_through,
dbo.tbl_Lifting_Gear.liftingNDT,
dbo.tbl_Lifting_Gear.liftingTest,
dbo.tbl_Lifting_Gear.e_defects,
dbo.tbl_Lifting_Gear.e_defects_desc,
dbo.tbl_Lifting_Gear.e_defects_date,
dbo.tbl_Lifting_Gear.e_defects_action,
dbo.tbl_Lifting_Gear.lift_department_id,
dbo.tbl_Lifting_Gear.lifting_loc
FROM dbo.tbl_equipment
INNER JOIN dbo.tbl_equip_swl_unit
ON dbo.tbl_equipment.e_swl_unit_id = dbo.tbl_equip_swl_unit.unit_id
INNER JOIN dbo.tbl_categories
ON dbo.tbl_equipment.e_cat_id = dbo.tbl_categories.category_id
INNER JOIN dbo.tbl_equip_depts
ON dbo.tbl_equipment.e_department_id = dbo.tbl_equip_depts.dept_id
INNER JOIN dbo.tbl_equip_man
ON dbo.tbl_equipment.e_manafacture_id = dbo.tbl_equip_man.man_id
INNER JOIN dbo.vwSubCategory
ON dbo.tbl_equipment.e_sub_id = dbo.vwSubCategory.category_id
INNER JOIN dbo.vwDescCategory
ON dbo.tbl_equipment.e_cat_id = dbo.vwDescCategory.category_id
INNER JOIN dbo.tbl_Lifting_Gear
ON dbo.tbl_equipment.equipment_id = dbo.tbl_Lifting_Gear.e_id
And here's the select statement with subquery that I am using:
SELECT *
FROM vw_LiftEquip
WHERE lifting_loc = ? AND
con_id = ? AND
EXPR11 =
'N'(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
)
ORDER BY lifting_ref_no,
category_id,
e_swl,
e_serial
I get the error :
Column "vw_LiftEquip.category_id" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.
Can't see why its returning that error, this is admittedly the first time I've ran a subquery on such a complex view, and I am a bit lost, thanks in advance for any help. I have looked through the similar posts and can find no answers to this one, sorry if I am just being dumb.
You are missing AND between EXPR11 = 'N' and (SELECT MAX(...
Otherwise, it looks OK. MAX without GROUP BY is allowed if you have no other columns in the SELECT
Update: #hvd also noted that you have nothing to compare to MAX(lifting_date). See comment
Update 2,
SELECT *
FROM vw_LiftEquip v1
CROSS JOIN
(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
) v2
WHERE v1.lifting_loc = ? AND
v1.con_id = ? AND
v1.EXPR11 = 'N'
ORDER BY v1.lifting_ref_no,
v1.category_id,
v1.e_swl,
v1.e_serial