I'm getting the error:
Error ORA-00933: SQL command not properly ended
When I run the following ORACLE query:
Select "col1", "col2"
from SCHEMANAME.TABLENAME
OFFSET 100 ROWS FETCH NEXT 100 ROWS ONLY
Any solutions?
My guess is that you are running Oracle < 12.2, where the fetch clause is not available.
A typical workaround uses window functions:
select col1, col2
from (
select t.*, row_number() over(order by id) rn
from schemaname.tablename t
) t
where rn between 101 and 200;
Note that, for both your original query and this query to produce a stable result, you need a column that deterministically defines the ordering of the rows. I assumed id.
If you do want an unstable sort, which I would not recommend, then use order by null in the over() clause of row_number().
Related
Edit: I am using Apache Hive (version 3.1.0.3.1.5.0-152)
When I run the following query:
insert into delta_table (select * from batch_table where loaddate=(select max(loaddate) from batch_table));
I get this error:
Unsupported SubQuery Expression 'loaddate': Only SubQuery expressions
that are top level conjuncts are allowed
We have a table that is written to in daily batches with the column loaddate that is unique for each batch. The purpose of the query is to get all the records from the most recent batch without knowing what it's load date is.
I suspect the issue is because I am using a subquery inside a subquery. Is there a way to change this query to do the same thing, but without the last subquery?
Depends on which version of hive you have , but you can use the Clause with to avoid the second subquery
with max_load as ( select max(loaddate) as loaddate from batch_table)
insert into delta_table
(select * from batch_table a where a.loaddate=max_load.loaddate);
It looks like the error was because the table was created incorrectly and for some reason this caused the query to fail. I recreated the table and it now works
Analytic function + filter will be more efficient than self-join or subquery with one more table scan to find max date:
insert into delta_table
select col1, col2, ... coln --list columns here
from
(
select t.*, rank() over(order by loaddate desc) rnk
from batch_table t
)s
where rnk=1;
This question already has answers here:
How do I limit the number of rows returned by an Oracle query after ordering?
(14 answers)
Closed 4 years ago.
I am trying to create query with kind of limit.
SELECT * FROM ALARMS WHERE OBJECT_ID=0 AND TIMESTAMP<=1525677504171 AND ROWNUM<=51 ORDER BY TIMESTAMP DESC
I use rownum but first it makes a limit and then it select ordered by. However I need to order first and then limit. I found here enter link description here that I should use FETCH FIRST 51 ROWS ONLY. Unfortunately it doesn't work.
SELECT * FROM ALARMS WHERE OBJECT_ID=0 AND TIMESTAMP<=1525677504171 ORDER BY TIMESTAMP DESC FETCH FIRST 51 ROWS ONLY;
It throws me following error:
SQL Error [933] [42000]: ORA-00933: SQL command not properly ended
oracle.jdbc.OracleDatabaseException: ORA-00933: SQL command not properly ended
You miss ONLY at the end. This syntax is available since 12c R1 if I remember correctly. Which Oracle version you use?
SELECT * FROM ALARMS WHERE OBJECT_ID=0 AND TIMESTAMP<=1525677504171 ORDER BY TIMESTAMP DESC FETCH FIRST 51 ROWS ONLY
;
Edit:
Since your version is 11g then try to use such syntax (I hope it will work;))
SELECT *
FROM (
SELECT a.*,ROW_NUMBER() OVER(ORDER BY TIMESTAMP DESC) rcnt
FROM ALARMS A WHERE OBJECT_ID=0 AND TIMESTAMP<=1525677504171) src
WHERE src.rcnt <= 51
ORDER BY src.TIMESTAMP desc;
FETCH FIRST is only available since Oracle 12c.
For the rownum approach, use a subquery that contains order by, then limit the rows in the enclosing query:
SELECT * FROM (
SELECT * FROM ALARMS WHERE OBJECT_ID=0 AND TIMESTAMP<=152567750417
ORDER BY TIMESTAMP DESC
) dt
WHERE ROWNUM<=51
I'm using Oracle SQL and i need some help with a query.
In the following query i'm selecting some rows with a simple condition (never mind hat kind of). From the output rows, i need to select the row with minimum value of DATE. For that, i'm using ROWNUM.
SELECT *
FROM(
SELECT NAME, DATE
FROM LIST
WHERE NAME = 'BLABLA'
ORDER by DATE)
WHERE ROWNUM = 1;
However, this query must fit to any other SQL languages, and therefore i need to write this query without ROWNUM.
Is there a simple way to write this query without using ROWNUM?
Unfortunately, row limit syntax differs between RDBMS.
The following is portable between SqlServer, Oracle and PostGres:
SELECT *
FROM (
SELECT NAME, DATE, ROW_NUMBER() OVER (ORDER by DATE) AS RowNum
FROM LIST
WHERE NAME = 'BLABLA'
) X
WHERE RowNum = 1;
However, other DB's syntax is different, e.g. MySql's LIMIT
select * from LIST
where Date=(select min(date) from LIST where Name='BLABLA' )
and Name='BLABLA'
I'm trying to developer the Oracle SQL version of the accepted answer here:
Return row of every n'th record
What I have so far is:
SELECT ROW_ID, CUST_ACCT_SITE_ID
FROM
(
SELECT CUST_ACCT_SITE_ID as CUST_ACCT_SITE_ID, ROW_NUMBER() OVER (ORDER BY CUST_ACCT_SITE_ID) AS ROW_ID
FROM XXDMX_VOICE_CUSTOMERS_TBL
) AS t
WHERE ROW_ID % 10000 = 0
ORDER BY CUST_ACCT_SITE_ID;
I get the error
ERROR
ORA-00933: SQL command not properly ended
I've tried lots of variations and can't think of what I am doing wrong. Any ideas, Oracle experts?
Try writing the query like this:
SELECT rn, CUST_ACCT_SITE_ID
FROM (SELECT CUST_ACCT_SITE_ID as CUST_ACCT_SITE_ID,
ROW_NUMBER() OVER (ORDER BY CUST_ACCT_SITE_ID) AS rn
FROM XXDMX_VOICE_CUSTOMERS_TBL
) t
WHERE mod(rn, 10000) = 0
ORDER BY CUST_ACCT_SITE_ID;
The primary difference is removing the as for the table alias. Oracle doesn't allow this syntax. I also changed row_id to something else, because "rowid" means something in Oracle and its use could be confusing (see here).
In PL/SQL (the name for "Oracle SQL"), the modulus operator uses this syntax:
WHERE MOD(ROW_ID, 10000) = 0
While using SELECT TOP 5 * FROM SOMETABLE gives me an error
ORA-00923: FROM keyword not found where expected
I am using Oracle 11g . I am aware of using rownum for doing the same thing but just wondering SQL TOP usage is not at all supported in Oracle ? Anything need to do extra to make SQL TOP working in Oracle ??
Oracle does not support TOP. Use ROWNUM
SELECT * FROM your_table
WHERE ROWNUM <= 5
SQLFiddle example
No, Oracle does not support TOP.
As you point out, the best approach is to use rownum. Another option is the analytical function ROW_NUMBER.
The rownum keyword, while it gets you the said no. of records, does so only after applying the order by clause if you have one.
So if the SQL server query is as below, it will give you 10 most recently created records.
Select TOP 10 * from mytable order by created_date desc
But to fit Oracle, when you write this, it gets you the 10 records (that may not be the most recent ones) and arranges them in descending order, which is not what you wanted.
Select * from mytable where rownum < 10 order by created_date desc
So writing with an additional select like this would help:
SELECT * FROM (Select * from mytable order by created_date desc) where rownum < 10
SQL TOP does NOT work for Oracle.