ORA-00904: Invalid column name on a correlated subquery - sql

I'm having a problem correlating a subquery on Oracle 8i
That subquery gives me an ORA-00904: Invalid column name, I don't understand why. Shouldn't it work?
SELECT
HIST_FA.HIFA_PLAN_CODIGO AS FE_CODIGO_PLANTEL,
HIST_FA.HIFA_NUMERO AS FE_NUMERO_CONTROL,
HIST_FA.HIFA_FECHA AS FE_FECHA_HORA_EMISION,
HIST_FA.HIFA_DEST_CLIE_CODIGO AS FE_CODIGO_CLIENTE,
-- . . . a bunch of other columns . . .
FROM
VFA_HIST_FA HIST_FA,
VFA_HIST_ITEMS_FA HIST_ITEMS_FA,
(
SELECT
HIRF_HIIF_HIFA_NUMERO AS FE_NUMERO_CONTROL,
SUM(DECODE(HIRF_RETE_CODIGO, 0, HIRF_MONTO)) AS FE_MONTO_ENTREGADO,
SUM(DECODE(HIRF_RETE_CODIGO, 5, HIRF_MONTO)) AS FE_IMPUESTO_UNICO,
SUM(DECODE(HIRF_RETE_CODIGO, 6, HIRF_MONTO)) AS FE_MARGEN_COMERCIALIZACION
FROM
VFA_HIST_ITEMS_RETENC_FA
WHERE
HIRF_HIIF_HIFA_NUMERO = HIST_FA.HIFA_NUMERO
GROUP BY
HIRF_HIIF_HIFA_NUMERO
) PP
WHERE
HIST_FA.HIFA_NUMERO = HIST_ITEMS_FA.HIIF_HIFA_NUMERO;
Of course, I can do this at the main WHERE, but then it scans all rows in the inner one.
HIST_FA.HIFA_NUMERO = PP.FE_NUMERO_CONTROL
So, not an option, since the query becomes everlasting.
Best regards!

Change the Alias Name for the column name
HIRF_HIIF_HIFA_NUMERO AS FE_NUMERO_CONTROL
to some other name and try again.

Related

Ambigously defined column in a subquery

I've the following subquery in an sql query:
(
SELECT ID_PLAN, ID_CURSO, NEDICION, NOMBRE AS NOMBREUNIDAD FROM ASISTEN, ALUMNOS, UNIDADES
WHERE ASISTEN.COD = ALUMNOS.COD AND UNIDADES.IDESTRUCTURA = ALUMNOS.IDESTRUCTURA
AND UNIDADES.CDUNDORG = ALUMNOS.CDUNDORG
AND UPPER(TRANSLATE(UNIDADES.NOMBRE, 'áéíóúÁÉÍÓÚ', 'aeiouAEIOU')) LIKE '%CONSEJERIA%'
GROUP BY ID_PLAN, ID_CURSO, NEDICION) ASIS
Problem I have I believe lies in that both table ALUMNOS and UNIDADES have a column named 'NOMBRE' so if I attempt to execute the query I obtain:
00000 - "column ambiguously defined"
To avoid that I thought about changing NOMBRE AS NOMBREUNIDAD to:
UNIDADES.NOMBRE AS NOMBREUNIDAD
But if I do that I get a:
00000 - "not a GROUP BY expression"
So, I don't know what to do so that subquery executes properly.
What should I change to properly execute query without changing the column name?
Aliases are pretty useful, if you use them. The simplify queries and make them easier to read and maintain. I'd suggest you to do so, as it'll also help query to work because Oracle doesn't know which table you actually meant when you selected those 4 columns - which tables do they belong to?
This is just a guess as I don't know your tables so you'll have to fix it yourself. Also, I literally JOINed tables; try to avoid comma-separating them in FROM clause and doing join in WHERE clause as it is supposed to filter data.
GROUP BY, as already commented, is probably useless. If you wanted to fetch distinct set of values, then use appropriate keyword: distinct.
SELECT DISTINCT n.id_plan,
s.id_curso,
u.nedicion,
u.nombre
FROM asisten n
JOIN alumnos s ON n.cod = s.cod
JOIN unidades u
ON u.idestructura = s.idestructura
AND u.cdundorg = s.cdundorg
WHERE UPPER (TRANSLATE (u.nombre, 'áéíóúÁÉÍÓÚ', 'aeiouAEIOU')) LIKE '%CONSEJERIA%'
I managed to solve my problem:
(
SELECT ID_PLAN, ID_CURSO, NEDICION, UNIDADES.NOMBRE AS NOMBREUNIDAD
FROM ASISTEN, ALUMNOS, UNIDADES
WHERE ASISTEN.COD = ALUMNOS.COD AND UNIDADES.IDESTRUCTURA = ALUMNOS.IDESTRUCTURA
AND UNIDADES.CDUNDORG = ALUMNOS.CDUNDORG
AND UPPER(TRANSLATE(UNIDADES.NOMBRE, 'áéíóúÁÉÍÓÚ', 'aeiouAEIOU')) LIKE '%CONSEJERIA%'
GROUP BY UNIDADES.NOMBRE,ID_PLAN, ID_CURSO, NEDICION
)

SQL: delete only if subquery (containing 0, 1, or more rows) equals scalar value

Description
I'm trying to do something like:
DELETE FROM ...
-- `<my_id>` is any given long scalar value
WHERE <my_id> = (SELECT id FROM ... WHERE ...);
That syntax is not entirely correct. If the select subquery contains more than one row, then we get an error like:
Scalar subquery contains more than one row
However, my intended purpose is indeed:
if the subquery returns exactly 1 value equal to the scalar value (<my_id>) ==> delete
else (0, or 2 or more values, or 1 non-equal value) ==> do not delete (ignore)
Question
I do not want neither IN nor EXISTS. I need rather something like "equals", which can compare a scalar value against possibly multi-valued rows.
What is the syntax in SQL for that?
Stack
In particular, I'm testing this with H2.
One method is:
DELETE FROM ...
WHERE <my_id> IN (SELECT id FROM ... WHERE ...) AND
(SELECT COUNT(*) FROM . . . WHERE . . .) = 1;
However, this is more simply written as:
DELETE FROM ...
WHERE <my_id> = (SELECT MAX(id)
FROM . . .
WHERE . .
HAVING COUNT(*) = 1
) ;
If the count is not 1, then the subquery returns nothing and there is no match (so nothing is deleted).

An object or column name is missing or empty. But its not?

I am on the 7th set of queries I have been working on and all of them have used SELECT * INTO some_table without an issue. For some reason tho the below query in SQL Server is throwing the error
An object or column name is missing or empty. For SELECT INTO
statements, verify each column has a name. For other statements, look
for empty alias names. Aliases defined as "" or [] are not allowed.
Change the alias to a valid name.
Any Idea on what it could be?
Note that running the query without the select into will result in data being returned and displayed as expected.
Select * into MYDB.MY_TBL
SELECT OT.U_ID AS "U_ID"
,R.E AS "E"
,R.IR AS "CKT"
,A.RI AS "OC"
,A.EQ AS "SEQ"
,A.HA AS "CHA"
,A.A_HA AS "ATE"
,A.BIL AS "BIL"
,A.CHA AS "CHAA"
,A.RAT AS "AMT"
,A.PRM AS "PREM"
,A.T_CHG AS "RAT"
,A.PER AS "LAS"
,A.S_BIL AS "BIL_A"
,A.CD AS "CDE"
,A.CBIL_J AS "BIL_J"
,A.AMT_D AS "TB"
,A.CRY AS "CTRY"
,A.RVW AS "RVW"
FROM MYDB.OTHER_TBL OT
JOIN [LINKEDSERVER\INST,0000].FE.dbo.tblR R
ON OT.E = R.E
JOIN [LINKEDSERVER\INST,0000].FE.dbo.tblA A
ON R.IR = A.IR
WHERE OT.U_ID = 'TEST'
You have two selects. I think you just want:
SELECT OT.U_ID AS "U_ID",
. . .
INTO MYDB.MY_TBL
FROM . . .
The INTO should follow the SELECT column list.
Or alternatively, you could use a subquery, but that does not seem necessary.
Where #GordonLinoff example works I realized what I forgot and it was my FROM () sub-query setup I normally use.
I will provide an example in contrast to Gordon's method.
IE:
Select * into MYDB.MY_TBL
FROM(
SELECT OT.U_ID AS "U_ID"
...
FROM MYDB.OTHER_TBL OT
WHERE OT.U_ID = 'TEST'
) SUB
Please note these two points:
1.You have two columns with given "CHA" alias
2.It Seems you need to rewrite the query as:
SELECT OT.U_ID AS "U_ID"
,R.E AS "E"
,R.IR AS "CKT"
,A.RI AS "OC"
,A.EQ AS "SEQ"
,A.HA AS "CHA_DUPLICATE"
,A.A_HA AS "ATE"
,A.BIL AS "BIL"
,A.CHA AS "CHA_DUPLICATE2"
,A.RAT AS "AMT"
,A.PRM AS "PREM"
,A.T_CHG AS "RAT"
,A.PER AS "LAS"
,A.S_BIL AS "BIL_A"
,A.CD AS "CDE"
,A.CBIL_J AS "BIL_J"
,A.AMT_D AS "TB"
,A.CRY AS "CTRY"
,A.RVW AS "RVW"
INTO MYDB.MY_TBL -- <<<<<<< NOTE
FROM MYDB.OTHER_TBL OT
JOIN [LINKEDSERVER\INST,0000].FE.dbo.tblR R
ON OT.E = R.E
JOIN [LINKEDSERVER\INST,0000].FE.dbo.tblA A
ON R.IR = A.IR
WHERE OT.U_ID = 'TEST'

Postgresql "subquery in FROM must have an alias" error

I'm doing a quick query using Postgresql 8.2 and I've done queries like this a thousand times before, but I can't figure out why I'm getting this error. I probably am missing something obvious, but it's saying my "subquery in FROM must have an alias". I do have an alias for my subquery "inner", and I can't figure out why else I would be getting the error.
SELECT "Branch", "Zip_5", "CountofStops", avg("EarlyTime") As
"Average_Arrival_Time"
FROM
(SELECT branch_id as "Branch", substring(stop_zip_postal_code, 1, 5) as
"Zip_5", count(stop_name) as "CountofStops", min(actual_arrival_time) as
"EarlyTime"
FROM distribution_stop_information
WHERE company_no = '001' AND route_date > '3/13/2017'
GROUP BY branch_id, stop_zip_postal_code)
inner
GROUP BY "Branch", "Zip_5"
ORDER BY Zip_5
********** Error **********
ERROR: subquery in FROM must have an alias
SQL state: 42601
Hint: For example, FROM (SELECT ...) [AS] foo.
inner is a reserved keyword. Use another name as alias.
inner . . . think "inner join". You need a better alias than that.
SELECT Branch, Zip_5, CountofStops, avg(EarlyTime) As Average_Arrival_Time
FROM (SELECT branch_id as Branch, left(stop_zip_postal_code, 5) as Zip_5,
count(stop_name) as CountofStops,
min(actual_arrival_time) as EarlyTime
FROM distribution_stop_information
WHERE company_no = '001' AND route_date > '2017-03-13'
GROUP BY branch_id, stop_zip_postal_code
) b
GROUP BY Branch, Zip_5
ORDER BY Zip_5;
Notes:
Don't wrap column names in double quotes unless needed. They are just superfluous.
Use standard formats for date constants.
LEFT() is a convenient shorthand for substring( . . ., 1, . . .)

ORA-00904: "CTN_QUANTITY": - "%s: invalid identifier"

I try to select rows where CTN_QUANTITY is not empty. My query
select distinct SDB.CTN_MAIN as S_CTN_MAIN,
SDB.SUBS_KEY as S_SUBS_KEY,
SDB.BAN_KEY as S_BAN_KEY,
count(SDB.CTN_MAIN) as CTN_QUANTITY,
FPCN.BAN_KEY as BAN_KEY
from STG_SDB_LOAD SDB, FCT_PREP_CHARGES_N FPCN
where FPCN.business_service_key = 33006
and CTN_QUANTITY <> ''
group by SDB.CTN_MAIN,
SDB.SUBS_KEY,
SDB.BAN_KEY,
FPCN.BAN_KEY;
I get error
ORA-00904. - "%s: invalid identifier"
What do I need to change?
CTN_QUANTITY is defined as the alias for an expression in the SELECT clause. But you want to use it in the WHERE clause. That will not work - WHERE is processed before SELECT. You will have to use count(SDB.CTN_MAIN) in the WHERE clause, not its alias.
Then: The count is always a number, but you are comparing it to the empty string. Which in Oracle is NULL, but regardless, it doesn't make sense. And, the COUNT may be zero, it should never be NULL.
You probably need to write WHERE count(....) <> 0.
Edit: And, of course, as discussed in Comments below... a COUNT filter does not belong in the WHERE clause, it should be in a HAVING clause.
You must use IS NOT NULL in place of <> . Also you cannot use alias in and clause.
select a.* from
(SELECT DISTINCT SDB.CTN_MAIN AS S_CTN_MAIN,
SDB.SUBS_KEY AS S_SUBS_KEY,
SDB.BAN_KEY AS S_BAN_KEY,
COUNT (SDB.CTN_MAIN) AS CTN_QUANTITY,
FPCN.BAN_KEY AS BAN_KEY
FROM STG_SDB_LOAD SDB, FCT_PREP_CHARGES_N FPCN
WHERE FPCN.business_service_key = 33006
GROUP BY SDB.CTN_MAIN,
SDB.SUBS_KEY,
SDB.BAN_KEY,
FPCN.BAN_KEY ) a
WHERE a.CTN_QUANTITY IS NOT NULL
Things to analyze : Is it really useful to have such condition a.CTN_QUANTITY IS NOT NULL. May be you can learn more by reseraching on this and considering #mathguy suggestion.