I am running into the error stated in the Title when I attempt to use the alias of a decode in my select statement. Here is the code:
SELECT DISTINCT rl.complaint_date,
decode(rl.judgement_date,null,rl.complaint_amt,rl.judgement_amt) as account_amt,
rl.date_served1,
rl.date_served2,
rl.judgement_date,
rl.skip_locate,
rl.case_no,
lcc.bal_range_min,
lcc.bal_range_max,
lcc.cost_range_min,
lcc.cost_range_max,
lcc.court,
lcc.county AS lcc_county,
ah.ACCOUNT,
ah.transaction_code,
ah.transaction_date,
ah.rule_id,
ah.amount,
ah.description,
r.state,
r.zip_code,
z.county AS ah_county,
z.county_2,
z.county_3,
z.county_4
FROM legal_address_skip las,
racctrel r,
ziplist z,
legal_court_cost lcc,
racctlgl rl,
legal_transaction_review ah
WHERE ah.ACCOUNT = rl.ACCOUNT
AND ah.ACCOUNT = las.ACCOUNT(+)
AND ah.ACCOUNT = r.ACCOUNT
AND nvl(lpad(substr(r.zip_code,0,instr(r.zip_code,'-')-1),5,0), substr(r.zip_code,1,5)) = z.zip
AND r.state = lcc.state
AND (REPLACE(lcc.county,' ','') = REPLACE(upper(z.county),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_2),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_3),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_4),' ',''))
AND lcc.transaction_code = ah.transaction_code
AND lcc.transaction_code = 1
AND lcc.end_date IS NULL
AND ah.amount NOT BETWEEN lcc.cost_range_min AND lcc.cost_range_max
AND (account_amt NOT BETWEEN lcc.bal_range_min AND lcc.bal_range_max
OR lcc.bal_range_min - account_amt NOT BETWEEN 0 AND 500)
ORDER BY CASE
WHEN ah.amount NOT BETWEEN lcc.cost_range_min AND lcc.cost_range_max THEN 1
WHEN ah.amount BETWEEN lcc.cost_range_min AND lcc.cost_range_max THEN 2 END, ah.amount;
I've used aliases before in select statements so I'm confused on why I am getting an error for this. Does it work differently in this situation?
From the documentation (emphasis added):
You can use a column alias, c_alias, to label the immediately
preceding expression in the select list so that the column is
displayed with a new heading. The alias effectively renames the select
list item for the duration of the query. The alias can be used in the
ORDER BY clause, but not other clauses in the query.
So you can't refer to the alias in the where clause, where at the moment you have:
...
AND (account_amt NOT BETWEEN ...
...
The alias isn't valid at that point, so it's looking for a column with that name in one of the tables, and doesn't find one. It's fine in the order by though.
You either need to replace the alias with the repeated decode statement, or possibly use a subquery and then refer to the alias in a where clause in an outer query, but that might end up being less efficient depending on how selective your other conditions are.
Oracle runs the select query in the order below:
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
Based on the above, you can see that when you are in the WHERE part, the alias has not yet been created. If you would like to use results from the SELECT part, you can do that by modifying your query like this:
WITH q AS
(
-- Your query without the extra AND
)
SELECT *
FROM q
WHERE --put your check here
This way you will already have the alias available when you reach the WHERE part.
Hope this helps! :)
Related
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
)
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'
I created the column frfpost_short but now I am having trouble making the column usable in a query.
select t.corridor,
s.corridor_code_rb,t.roadway,s.SVYLENG2012,
round(cast(t.frfpost as float),3)) as frfpost_short,
s.FRFPOST,s.BEG_GN
from SEC_FILE_IMPORT_2014 t,NORTH_VAN_DATA_VIEW_MOD_032015 s,
where frfpost_short = s.FRFPOST -- This line is causing problems
-- I would like to make frfpost_short queryable
and t.corridor = s.CORRIDOR_CODE
order by 1
Use a subquery or repeat the expression. Aliases defined in the select are not available in the where:
select t.corridor,
s.corridor_code_rb,t.roadway, s.SVYLENG2012,
round(cast(t.frfpost as float), 3) as frfpost_short,
s.FRFPOST, s.BEG_GN
from SEC_FILE_IMPORT_2014 t join
NORTH_VAN_DATA_VIEW_MOD_032015 s
on round(cast(t.frfpost as float), 3) = s.FRFPOST and
t.corridor = s.CORRIDOR_CODE
order by 1
I fixed your query. In particular, learn to use explicit join syntax.
You can't use aliases in where clause, you need to use below solution
select t.corridor,
s.corridor_code_rb,t.roadway,s.SVYLENG2012,
round(cast(t.frfpost as float),3)) as frfpost_short,
s.FRFPOST,s.BEG_GN
from SEC_FILE_IMPORT_2014 t,NORTH_VAN_DATA_VIEW_MOD_032015 s,
where round(cast(t.frfpost as float),3)) = s.FRFPOST
and t.corridor = s.CORRIDOR_CODE
order by 1
I am running into the error stated in the Title when I attempt to use the alias of a decode in my select statement. Here is the code:
SELECT DISTINCT rl.complaint_date,
decode(rl.judgement_date,null,rl.complaint_amt,rl.judgement_amt) as account_amt,
rl.date_served1,
rl.date_served2,
rl.judgement_date,
rl.skip_locate,
rl.case_no,
lcc.bal_range_min,
lcc.bal_range_max,
lcc.cost_range_min,
lcc.cost_range_max,
lcc.court,
lcc.county AS lcc_county,
ah.ACCOUNT,
ah.transaction_code,
ah.transaction_date,
ah.rule_id,
ah.amount,
ah.description,
r.state,
r.zip_code,
z.county AS ah_county,
z.county_2,
z.county_3,
z.county_4
FROM legal_address_skip las,
racctrel r,
ziplist z,
legal_court_cost lcc,
racctlgl rl,
legal_transaction_review ah
WHERE ah.ACCOUNT = rl.ACCOUNT
AND ah.ACCOUNT = las.ACCOUNT(+)
AND ah.ACCOUNT = r.ACCOUNT
AND nvl(lpad(substr(r.zip_code,0,instr(r.zip_code,'-')-1),5,0), substr(r.zip_code,1,5)) = z.zip
AND r.state = lcc.state
AND (REPLACE(lcc.county,' ','') = REPLACE(upper(z.county),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_2),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_3),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_4),' ',''))
AND lcc.transaction_code = ah.transaction_code
AND lcc.transaction_code = 1
AND lcc.end_date IS NULL
AND ah.amount NOT BETWEEN lcc.cost_range_min AND lcc.cost_range_max
AND (account_amt NOT BETWEEN lcc.bal_range_min AND lcc.bal_range_max
OR lcc.bal_range_min - account_amt NOT BETWEEN 0 AND 500)
ORDER BY CASE
WHEN ah.amount NOT BETWEEN lcc.cost_range_min AND lcc.cost_range_max THEN 1
WHEN ah.amount BETWEEN lcc.cost_range_min AND lcc.cost_range_max THEN 2 END, ah.amount;
I've used aliases before in select statements so I'm confused on why I am getting an error for this. Does it work differently in this situation?
From the documentation (emphasis added):
You can use a column alias, c_alias, to label the immediately
preceding expression in the select list so that the column is
displayed with a new heading. The alias effectively renames the select
list item for the duration of the query. The alias can be used in the
ORDER BY clause, but not other clauses in the query.
So you can't refer to the alias in the where clause, where at the moment you have:
...
AND (account_amt NOT BETWEEN ...
...
The alias isn't valid at that point, so it's looking for a column with that name in one of the tables, and doesn't find one. It's fine in the order by though.
You either need to replace the alias with the repeated decode statement, or possibly use a subquery and then refer to the alias in a where clause in an outer query, but that might end up being less efficient depending on how selective your other conditions are.
Oracle runs the select query in the order below:
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
Based on the above, you can see that when you are in the WHERE part, the alias has not yet been created. If you would like to use results from the SELECT part, you can do that by modifying your query like this:
WITH q AS
(
-- Your query without the extra AND
)
SELECT *
FROM q
WHERE --put your check here
This way you will already have the alias available when you reach the WHERE part.
Hope this helps! :)
In Oracle 11g, I came across an error for a query and cannot figure why it is erroring on me. Here is the query:
select
main_data.issue_number,
main_data.transaction_number
from
(
select
p1.payment_date,
p1.media_number,
p1.payment_amount,
p1.issue_number,
p1.advice_na_number,
name.name_address_line_1,
name.name_address_line_2,
name.name_address_line_3,
name.name_address_line_4,
name.name_address_line_5,
name.name_address_line_6,
name.name_address_line_7,
name.name_address_city,
name.state_code,
name.address_country_code,
name.zip_code,
name.tax_id_number,
p1.output_tx_number_prin,
p1.output_tx_number_int,
'' as "transaction_number",
p1header.check_account_number
from
p1
left join name on p1.name_address_number = name.name_address_number
left join p1header on p1.issue_number = p1header.issue_number
UNION ALL
select
check.date_of_payment,
check.media_number,
check.payment_amount,
check.issue_number,
check.payee_na_number,
name.name_address_line_1,
name.name_address_line_2,
name.name_address_line_3,
name.name_address_line_4,
name.name_address_line_5,
name.name_address_line_6,
name.name_address_line_7,
name.name_address_city,
name.state_code,
name.address_country_code,
name.zip_code,
name.tax_id_number,
'' as "output_tx_number_prin",
'' as "output_tx_number_int",
check.transaction_number,
check.dda_number as "check_account_number"
from check
left join name on check.payee_na_number = name.name_address_number
) main_data
Selecting individual fields like above will give me an "invalid identifier error". If I do select * then it gives me back the data without any error. What am I doing wrong here? Thank you.
The old quoted identifier problem... see point 9 in the database object naming documentation, and note that Oracle does not recommend using quoted identifiers.
You've put your column alias as lower case inside double-quotes. That means that any references to it also have to be quoted and exactly match the case. So this would work:
select
main_data.issue_number,
main_data."transaction_number"
from
...
But unless you have a burning need to have that alias like that - and I doubt you do as all the identifier names from the actual table columns are not quoted - it would be simpler to remove the double quotes from the inner selects:
select
main_data.issue_number,
main_data.transaction_number
from
(
select
...
'' as transaction_number,
p1header.check_account_number
...
UNION ALL
select
...
'' as output_tx_number_prin,
'' as output_tx_number_int,
check.transaction_number,
check.dda_number as check_account_number
...
You don't actually need to alias the columns in the second branch of the union; the column identifiers will all be taken from the first branch.