Missing Expression for the Oracle query - sql

I am trying to run this query but I am getting a Missing Expression error.
SELECT *
FROM (
SELECT ROW_NUMBER() OVER(order by 'rownum') row_num1,
*
FROM A
WHERE refresh_date = (
SELECT max(refresh_date)
FROM A
WHERE upper(flaw_table_name) = upper('B')
)
)
WHERE row_num1 >= 1
AND row_num1 <=20
Can you please help me out, where I am getting wrong.

You have a constant in the order by clause. In addition, it is redundant to put rownum there in the first place. Just use rownum.
I think you want:
SELECT A.*
FROM A
WHERE refresh_date = (SELECT max(refresh_date)
FROM A
WHERE upper(flaw_table_name) = upper('B')
) AND
rownum between 1 and 20;
The subquery is not necessary and Oracle is smart enough to evaluate the rownum expression after the other conditions in the WHERE clause.

select star is in Oracle(?) not possible to combine with other explicite columns. You need to qualify the star with the alias A in the subquery.
SELECT ROW_NUMBER() OVER(order by 'rownum') row_num1,
A.*
FROM A
This is causing the Missing Expression error - after that you will see other errors

you have to add an alias, you cannot use * without a name if you're using other colnames or functions too
SELECT *
FROM (SELECT row_number() over(ORDER BY 'rownum') row_num1,
t.*
FROM a t
WHERE refresh_date =
(SELECT MAX(refresh_date)
FROM a
WHERE upper(flaw_table_name) = upper('B')))
WHERE row_num1 >= 1
AND row_num1 <= 20

SELECT * from (
select ROW_NUMBER() OVER(order by 'rownum') row_num1, * from A
where refresh_date = ( Select max(refresh_date)
from A
where upper(flaw_table_name) = upper('B')
)
) where row_num1>= 1 and row_num1<=20
replace last where clause with "and" as where is already present in query

Related

oracle db from keyword not found where expected in double cte

I have a double cte expression , the first one join two tables and the second is implementing a partition by function:
with cte as (
select *
from memuat.product p
join memuat.licence l on p.id = l.product_id
where l.managed = 'TRUE'
),
joined as (
select
*,
row_number() over (partition by id order by id) as rn
from cte
)
select * from joined;
I get the following error:
ORA-00923: FROM keyword not found where expected, ERROR at line 12.
I cannot figure out which syntax error is wrong in my query.
Oracle is nitpicking when it comes to SELECT *. SELECT * means "select everything", so how can you possibly add something to it? In Oracle you cannot SELECT *, 1 AS something_else FROM some_table. You must have SELECT some_table.*, 1 AS something_else FROM some_table, so you are no longer selecting "everything", but "everything from the table" :-)
You have
select
*,
row_number() over (partition by id order by id) as rn
from cte
It must be
select
cte.*,
row_number() over (partition by id order by id) as rn
from cte
instead.

ORDER BY upper(...) with a UNION giving me problems

I'm having a bit of trouble figuring out why I'm having this problem.
This code works exactly how it should. It combines the two tables (MESSAGES and MESSAGES_ARCHIVE) and orders them correctly.
SELECT * FROM (
SELECT rownum as rn, a.* FROM (
SELECT
outbound.FROM_ADDR, outbound.TO_ADDR, outbound.EMAIL_SUBJECT
from MESSAGES outbound
where (1 = 1)
UNION ALL
SELECT
outboundarch.FROM_ADDR, outboundarch.TO_ADDR, outboundarch.EMAIL_SUBJECT
from MESSAGES_ARCHIVE outboundarch
where (1 = 1)
order by FROM_ADDR DESC
) a
) where rn between 1 and 25
However, this code does not work.
SELECT * FROM (
SELECT rownum as rn, a.* FROM (
SELECT
outbound.FROM_ADDR, outbound.TO_ADDR, outbound.EMAIL_SUBJECT
from MESSAGES outbound
where (1 = 1)
UNION ALL
SELECT
outboundarch.FROM_ADDR, outboundarch.TO_ADDR, outboundarch.EMAIL_SUBJECT
from MESSAGES_ARCHIVE outboundarch
where (1 = 1)
order by upper(FROM_ADDR) DESC
) a
) where rn between 1 and 25
and returns this error
ORA-01785: ORDER BY item must be the number of a SELECT-list expression
01785. 00000 - "ORDER BY item must be the number of a SELECT-list expression"
I'm trying to get the two tables ordered regardless of letter case, which is why I'm using upper(FROM_ADDR). Any suggestions? Thanks!
I'm not quite sure why this is generating an error, but it probably has to do with scoping rules for union queries. There is an easy work-around, using row_number():
SELECT * FROM (
SELECT row_number() over (order by upper(FROM_ADDR)) as rn, a.*
FROM (
SELECT
outbound.FROM_ADDR, outbound.TO_ADDR, outbound.EMAIL_SUBJECT
from MESSAGES outbound
where (1 = 1)
UNION ALL
SELECT
outboundarch.FROM_ADDR, outboundarch.TO_ADDR, outboundarch.EMAIL_SUBJECT
from MESSAGES_ARCHIVE outboundarch
where (1 = 1)
) a
)
where rn between 1 and 25
Your upper() is returning a value, but not a column name.
Instead of:
order by upper(FROM_ADDR) DESC
try:
order by upper(FROM_ADDR) as FROM_ADDR DESC

PostgreSQL - Assigning window function to alias

I'm trying to set ROW_NUMBER()... as an alias so I can reference it in the OFFSET. e.g. OFFSET some_alias - 1. I need to get a single row including the ROW_NUMBER() from a larger query. Here's my working code (gets correct ROW_NUMBER(), but isn't offset by the right amount):
WITH FirstQuery AS (
SELECT "RepInitials", COUNT("OrderStatus"), ROW_NUMBER()OVER(ORDER BY COUNT("OrderStatus") DESC)
FROM "tblBulkSalesQuery"
WHERE "OrderStatus" = 'CMC'
GROUP BY "RepInitials"
)
SELECT "RepInitials", COUNT("OrderStatus"), ROW_NUMBER()OVER(ORDER BY COUNT("OrderStatus") DESC)
FROM "tblBulkSalesQuery"
WHERE "OrderStatus" = 'CMC'
GROUP BY "RepInitials"
LIMIT 1
OFFSET 1;
select *
from (
SELECT "RepInitials",
COUNT("OrderStatus") as order_status_count,
ROW_NUMBER() OVER (ORDER BY COUNT("OrderStatus") DESC) as rn
FROM "tblBulkSalesQuery"
WHERE "OrderStatus" = 'CMC'
GROUP BY "RepInitials"
) as t
where rn = 1
Edit:
The t is an alias for the nested select ("derived table"). PostgreSQL requires each derived table to get it's own "name" and that can only be done by assigning a alias.
It's pretty much the same as:
with t as (
... here goes the real select ...
)
select *
from t
where rn = 1;

SQL: Use a calculated fields from the SELECT in the WHERE clause

I have a SQL query that does some ranking, like this:
SELECT RANK() OVER(PARTITION BY XXX ORDER BY yyy,zzz,oooo) as ranking, *
FROM SomeTable
WHERE ranking = 1 --> this is not possible
I want to use that ranking in a WHERE condition at the end.
Now I nest this query in another query and do filtering on the ranking there, but is there no easier or faster way to filter on such values from the SELECT statement?
Use a CTE (Common Table Expression) - sort of an "inline" view just for the next statement:
;WITH MyCTE AS
(
SELECT
RANK() OVER(PARTITION BY XXX ORDER BY yyy,zzz,oooo) as ranking,
*
FROM SomeTable
)
SELECT *
FROM MyCTE
WHERE ranking = 1 --> this is now possible!
Sorry for the former posting, i forgot : windowing functions can only be used in select or order by clauses.
You'll have to use a sub query:
SELECT * FROM
(
SELECT RANK() OVER(PARTITION BY XXX ORDER BY yyy,zzz,oooo) as ranking, *
FROM SomeTable
) t
WHERE ranking = 1
OR A CTE.
select * from (
select RANK() OVER(PARTITION BY name ORDER BY id) as ranking, *
from PostTypes
) A
where A.ranking = 1
https://data.stackexchange.com/stackoverflow/query/edit/59515

Select Nth Row From A Table In Oracle

How can I select the Nth row from a table in Oracle?
I tried
SELECT PRICE FROM AAA_PRICING WHERE ROWNUM = 2
but that didn't work. Please help!
Based on the classic answer:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:127412348064
select *
from ( select a.*, rownum rnum
from ( YOUR_QUERY_GOES_HERE -- including the order by ) a
where rownum <= N_ROWS )
where rnum >= N_ROWS
/
Will not works with '=' (will works <2 or >2, but not equal)
so you can
SELECT Price from (SELECT PRICE, ROWNUM AS RN FROM AAA_PRICING) WHERE RN = 2
To address the reason for this:
The RowNum is a pseudo-column supplied by Oracle. It is generated while the SELECT-clause is being processed. Since the WHERE-clause is handled before the SELECT-clause, the RowNum does not have a proper value yet.
One can argue whether or not it makes sense to have Oracle throw an exception in situation, but because RowNum still is a pseudo-column it's still valid to have it there.
Note: Don't confuse this with RowId, which is an entire different story!
IMPORTANT EDIT:
Note that what I wrote about RowNum is only true for =, >, >=, IN () and maybe others. If you check for, e.g. RowNum < 10, you only get nine records!? I don't know why that is the case!
Select * From
(
Select Row_Number() OVER (Order by empno) rno, e.*
From scott.emp e
)
Where rno in (1, 3, 11)
SELECT PRICE
FROM (
SELECT PRICE,
ROWNUM rnum
FROM AAA_PRICING
ORDER BY PRICE ASC
)
WHERE rnum = 2
If you are on Oracle 12 or above, You can use the result offset and fetch clauses:
SELECT PRICE FROM AAA_PRICING
offset 1 rows fetch next 1 rows only
SELECT * FROM
(SELECT PRICE, ROWNUM AS RN FROM AAA_PRICING )
WHERE RN = 2;
select * from (Select Price, rownum as rn from(Select * from AAA_PRICING a order by a.Price))
where rn=2;
It will give you 2nd lowest price from the Price column. If you want simply 2nd row remove Order By condition.
ROWNUM is a pseudo column which generates unique pseudo values (equals to the number of records present in the SELECT statement o/p) during the execution of SELECT clause. When this pseudo column is specified with the WHERE clause it's value becomes 1 by default. So it behaves according to the comparison operator specified with it.
SELECT * FROM (
SELECT ROWNUM RN, E.*
FROM Emp E
)
WHERE RN = 10;
select *
From (select PRICE, DENSE_RANK() over(ORDER BY PRICE desc) as RNO
From AAA_PRICING
) t where RNO=2;
select a.*, rownum rnum
from ( select * from xyz_menu order by priority desc) a
where rownum < 5 ;
select * from xyz_menu order by priority desc
creating virtual table and also defining row number in virtual table
note: for oracle
Problem solved!
To select 2nd row in Oracle..
select SEN_NO,ITEM_NO from (select * from master_machine where
sen_no ='BGCWKKL23' and rownum <=2 order by
rownum desc,timestamp asc) where rownum <=1
Thank You!