FROM keyword not found - sql

I am getting an error, even though I actually do have the keyword!
Here's my code:
SELECT TOP(10) * FROM TABLE_NAME
Here's the error:
[42000][923] ORA-00923: FROM keyword not found where expected
What am I doing wrong?

Here is the right way of accessing top # rows
SELECT * FROM TABLE_NAME
WHERE ROWNUM <= 10

In general, you should not use top or limit or anything like that unless you are using order by. In Oracle, the traditional way to write your query is:
SELECT t.*
FROM TABLE_NAME
ORDER BY <something goes here>
WHERE rownum <= 10;
You can omit the ORDER BY, but then you will get an arbitrary set of 10 rows that might change from one call to another.

Related

"ORDER BY" in subquery - not avaliable in MonetDB?

I found that, when using order-by directly, it is ok.
SELECT t0."D" AS fd,
SUM(t0."SD") AS top
FROM "mock_table_1" AS t0
GROUP BY t0."D"
ORDER BY top ASC
LIMIT 10
but when using it in a subquery, an syntax error is reported.
SELECT * FROM (
SELECT t0."D" AS fd,
SUM(t0."SD") AS top
FROM "mock_table_1" AS t0
GROUP BY t0."D"
ORDER BY top ASC
LIMIT 10
)
here is the error message.
syntax error, unexpected ORDER, expecting UNION or EXCEPT or INTERSECT or ')' in: "select t0."A" as d0,
So, I wonder if monetdb is designed to be like this, or it is a bug?
that is the expected behavior. offset, limit, and order by are not allowed in subqueries
https://www.monetdb.org/pipermail/users-list/2013-October/006856.html
SQL-conforming DBMSes are not supposed to allow ORDER BY in subqueries, because it contradicts the conceptual model of a relational DBMS. See:
Is order by clause allowed in a subquery
for details. A way around that, however, is to use Window Functions, which MonetDB does support. Specifically, in your subquery, instead of, say,
SELECT c1 FROM t1;
you can
SELECT c1, ROW_NUMBER() OVER () as rownum from t1;
and now you have the relative order of the inner query result available to the outer query.

Why do partitions require nested selects?

I have a page to show 10 messages by each user (don't ask me why)
I have the following code:
SELECT *, row_number() over(partition by user_id) as row_num
FROM "posts"
WHERE row_num <= 10
It doesn't work.
When I do this:
SELECT *
FROM (
SELECT *, row_number() over(partition by user_id) as row_num FROM "posts") as T
WHERE row_num <= 10
It does work.
Why do I need nested query to see row_num column? Btw, in first request I actually see it in results but can't use where keyword for this column.
It seems to be the same "rule" as any query, column aliases aren't visible to the WHERE clause;
This will also fail;
SELECT id AS newid
FROM test
WHERE newid=1; -- must use "id" in WHERE clause
SQL Query like:
SELECT *
FROM table
WHERE <condition>
will execute in next order:
3.SELECT *
1.FROM table
2.WHERE <condition>
so, as Joachim Isaksson say, columns in SELECt clause are not visible in WHERE clause, because of processing order.
In your second query, column row_num are fetched in FROM clause first, so it will be visible in WHERE clause.
Here is simple list of steps in order they executes.
There is a good reason for this rule in standard SQL.
Consider the statement:
SELECT *, row_number() over (partition by user_id) as row_num
FROM "posts"
WHERE row_num <= 10 and p.type = 'xxx';
When does the p.type = 'xxx' get evaluated relative to the row number? In other words, would this return the first ten rows of "xxx"? Or would it return the "xxx"s in the first ten rows?
The designers of the SQL language recognize that this is a hard problem to resolve. Only allowing them in the select clause resolves the issue.
You can check this topic and this one on dba.stockexchange.com about order in which SQL executes SELECT clause. I think it aplies not only for PostgreSQL, but for all RDBMS.

Oracle 11g and SQL TOP query

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.

Clarification on "rownum"

I have a table Table1
Name Date
A 01-jun-2010
B 03-dec-2010
C 12-may-2010
When i query this table with the following query
select * from table1 where rownum=1
i got output as
Name Date
A 01-jun-2010
But in the same way when i use the following queries i do not get any output.
select * from table1 where rownum=2
select * from table1 where rownum=3
Someone please give me guidance why it works like that, and how to use the rownum.
Tom has an answer for many Oracle related questions
In short, rownum is available after the where clause has been applied and before the order by clause is applied.
In the case of RowNum=2, the predicate in the where clause will never evaluate to true as RowNum starts at 1 and only increases if records matching the predicate can be found.
Adding rownums is one of the last things done after the result set has been fetched from the database. This means that the first row will always have rownum 1. Rownum is better used when you want to limit the result set, for instance when doing paging.
See this for more: http://www.orafaq.com/wiki/ROWNUM
(Not an Oracle expert by any means)
From what I understand, rownum numbers the rows in a result set.
So, in your example:
select * from table1 where rownum=2
How many rows are there going to be in the result set? Therefore, what rownum would be assigned to such a row? Can you see now why no result is actually returned?
In general, you should avoid relying on rownum, or any features that imply an order to results. Try to think about working with the entire set of results.
With that being said, I believe the following would work:
select * from (select rownum as rn,table1.* from table1) as t where t.rn = 2
Because in that case, you're numbering the rows within the subquery.

Access Database LIMIT keyword

I'm trying to get my page listing function working in ASP with an Access database, but I don't know the alternative to LIMIT in Microsoft SQL. I have tried TOP but this doesn't seem to be working.
Here is the statement am using with MySQL:
SELECT * FROM customers ORDER BY customerName DESC LIMIT 0, 5
How can I convert this to work with Access Database?
According to ms-access view:
SELECT TOP(5) * FROM customers ORDER BY customerName;
will fetch an error "The SELECT statement includes a reserved word",
the correct syntax is:
SELECT TOP 5 * FROM customers ORDER BY customerName;
(note the brackets)..
Top(5) is deceptive. Internally the database returns all records, then Access just shows the Top 5 rows. I'd use the LIMIT keyword instead of Top(n).
There is no direct equivalent in access for LIMIT, but the TOP statement can be manipulated into working in a similar fashion to say, "... LIMIT BY 50, 250" etc,. I found out by experiment that if you wanted to get the "next 50" records at an offset of 250 you could try the following
SELECT * FROM (SELECT TOP 50 tab2.* FROM (SELECT TOP 300 tab1.* FROM my_table AS tab1 ORDER BY column_name ASC) AS tab2 ORDER BY column_name DESC) ORDER BY column_name ASC;
This should return the records from row 250 to 300, in ascending order (provided they exist.) with or without a unique index. A WHERE clause could tidy the results further if need be.
A little convoluted but I hope it helps.