Oracle select specific rows - sql

Can we select specific rows to range in oracle? for example, I have a table of 100 rows I have to select only a range of 10 to 20-row numbers. Is it possible to do that

You can do with an auxiliary operation. Firstly number the rows by row_number() function and then order by them :
select * from
(
select row_number() over (order by 0) rn, t.*
from tab t
)
where rn between 10 and 20;
but this is not a stable operation, since SQL statements are unordered sets. Therefore it's better to define a unique identity column and order depending on it.
Replace zero in the order by clause with some columns of your table to be able to reach a rigid ordering criteria. If a primary key column exists, it might be better to include only it in the order by list.

would LIMIT and OFFSET work?
ie.
SELECT * FROM table
LIMIT 20
OFFSET 20
will read rows 20 -> 40. Is this what you are trying to do?

Related

Select rows by index in Amazon Athena

This is a very simple question but I can't seem to find documentation on it. How one would query rows by index (ie select the 10th through 20th row in a table)?
I know there's a row_numbers function but it doesn't seem to do what I want.
Do not specify any partition so your row number will be an integer between 1 and your number of record.
SELECT row_num FROM (
SELECT row_number() over () as row_num
FROM your_table
)
WHERE row_num between 100000 and 100010
I seem to have found a roundabout and clunky way of doing this in Athena, so any better answers are welcome. This approach requires you have some numeric column in your table already, in this case named some_numeric_column:
SELECT some_numeric_column, row_num FROM (
SELECT some_numeric_column,
row_number() over (order by some_numeric_column) as row_num
FROM your_table
)
WHERE row_num between 100000 and 100010
To explain, you first select some numeric column in your data, then create a column (called row_num) of row numbers which is based on the order of your selected numeric column. Then you wrap that all in a select call because Athena doesn't support creating and then conditioning on the row_num column within a single call. If you don't wrap it in a second SELECT call Athena will spit out some errors about not finding a column named row_num.

Select first 50 rows then order

Is it possible to select the first 50 rows in Postgres with select * from yellow_tripdata_staging fetch first 50 rows only and after that sort the results by column?
If so, how?
edit: the table is really big, and is not really important which rows i get.
this question was because i was using Redash to visualise the data and was getting some weird order on the sorted results.then i realized that the column i was using to order was not numerical but char, which causes values like 11 and 10 to come before 2 and 3.
Im sorry for this dumb question
It's not completely clear how your first 50 rows are identified and in what order they shall be returned. There is no "natural order" in tables of a relational database. No guarantees without explicit ORDER BY.
However, there is a current physical order of rows you can (ab-)use. And by default that's the order in which rows have been inserted - as long as nothing else has happened to that table. But the RDBMS is free to change the physical order any time, so the physical order is not reliable. Results can and will change with write operations to the table (including VACUUM or other utility commands).
Let's call your column used to sort after 50 rows sort_col.
( -- parentheses required
TABLE yellow_tripdata_staging LIMIT 50
)
UNION ALL
( -- parentheses required
SELECT *
FROM (TABLE yellow_tripdata_staging OFFSET 50) sub
ORDER BY sort_col
);
More explanation (incl. TABLE and parentheses):
Is there a shortcut for SELECT * FROM in psql?
Get n grouped categories and sum others into one
Or, assuming sort_col is defined NOT NULL:
SELECT *
FROM yellow_tripdata_staging
ORDER BY CASE WHEN row_number() OVER () > 50 THEN sort_col END NULLS FIRST;
The window function row_number() is allowed to appear in the ORDER BY clause.
row_number() OVER () (with empty OVER clause) will attach serial numbers according to the current physical order of row - all the disclaimers above still apply.
The CASE expression replaces the first 50 row numbers with NULL, which sort first due to attached NULLS FIRST. In effect, the first 50 rows are unsorted the rest is sorted by sort_col.
Or, if you actually mean to take the first 50 rows according to sort_col and leave them unsorted, while the rest is to be sorted:
SELECT *
FROM yellow_tripdata_staging
ORDER BY GREATEST (row_number() OVER (ORDER BY sort_col), 50);
Or, if you just mean to fetch the "first" 50 rows according to current physical order or some other undisclosed (more reliable) criteria, you need a subquery or CTE to sort those 50 rows in the outer SELECT:
SELECT *
FROM (TABLE yellow_tripdata_staging LIMIT 50) sub
ORDER BY sort_col;
You need to define your requirements clearly.
You can order by two different columns. For instance:
select yts.*
from (select yts.*,
row_number() over (order by id) as seqnum
from yellow_tripdata_staging yts
) yts
order by (seqnum <= 50)::int desc,
(case when seqnum <= 50 then id end),
col

SQL , SELECT `column` FROM `table` ORDER BY RAND() LIMIT 10

I have a table that contains a number of items with ids, if I clicked on one of these ids I'd like to display the one I clicked, followed by 9 random entries.
The following query will select 10 rows randomly:
SELECT column FROM table ORDER BY RAND() LIMIT 10
How do I first display the item of my choice, and then the 9 items that were chosen at random?
What is the suitable query for this problem ??
Sounds like you just want a union.
SELECT column FROM table LIMIT 1
UNION ALL
SELECT column
FROM table
ORDER BY RAND()
LIMIT 9
Two things you may want to consider. First, if you don't put a nonrandom order by on the first query there is no guarantee what you will get as your first row or even that it is consistent. Also, you could end up selecting the same first row twice. To avoid that you can try:
SELECT column FROM table ORDER BY SOME_COLUMN LIMIT 1
UNION ALL
SELECT column
FROM table
WHERE COLUMN NOT IN(SELECT column FROM table ORDER BY SOME_COLUMN LIMIT 1)
ORDER BY RAND()
LIMIT 9
I would suggest using multiple conditions in the order by:
SELECT `column`
FROM `table`
ORDER BY (id = SELECTEDID) DESC, RAND()
LIMIT 10;
This will ensure two things. First, your selected row will be first (because of he order by). And second, you will get nine other rows in the 10.

How to retrieve the last 2 records from table?

I have a table with n number of records
How can i retrieve the nth record and (n-1)th record from my table in SQL without using derived table ?
I have tried using ROWID as
select * from table where rowid in (select max(rowid) from table);
It is giving the nth record but i want the (n-1)th record also .
And is there any other method other than using max,derived table and pseudo columns
Thanks
You cannot depend on rowid to get you to the last row in the table. You need an auto-incrementing id or creation time to have the proper ordering.
You can use, for instance:
select *
from (select t.*, row_number() over (order by <id> desc) as seqnum
from t
) t
where seqnum <= 2
Although allowed in the syntax, the order by clause in a subquery is ignored (for instance http://docs.oracle.com/javadb/10.8.2.2/ref/rrefsqlj13658.html).
Just to be clear, rowids have nothing to do with the ordering of rows in a table. The Oracle documentation is quite clear that they specify a physical access path for the data (http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#i6732). It is true that in an empty database, inserting records into a newtable will probably create a monotonically increasing sequence of row ids. But you cannot depend on this. The only guarantees with rowids are that they are unique within a table and are the fastest way to access a particular row.
I have to admit that I cannot find good documentation on Oracle handling or not handling order by's in subqueries in its most recent versions. ANSI SQL does not require compliant databases to support order by in subqueries. Oracle syntax allows it, and it seems to work in some cases, at least. My best guess is that it would probably work on a single processor, single threaded instance of Oracle, or if the data access is through an index. Once parallelism is introduced, the results would probably not be ordered. Since I started using Oracle (in the mid-1990s), I have been under the impression that order bys in subqueries are generally ignored. My advice would be to not depend on the functionality, until Oracle clearly states that it is supported.
select * from (select * from my_table order by rowid) where rownum <= 2
and for rows between N and M:
select * from (
select * from (
select * from my_table order by rowid
) where rownum <= M
) where rownum >= N
Try this
select top 2 * from table order by rowid desc
Assuming rowid as column in your table:
SELECT * FROM table ORDER BY rowid DESC LIMIT 2

Teradata - limiting the results using TOP

I am trying to fetch a huge set of records from Teradata using JDBC. And I need to break this set into parts for which I'm using "Top N" clause in select.
But I dont know how to set the "Offset" like how we do in MySQL -
SELECT * FROM tbl LIMIT 5,10
so that next select statement would fetch me the records from (N+1)th position.
RANK and QUALIFY I beleive are your friends here
for example
SEL RANK(custID), custID
FROM mydatabase.tblcustomer
QUALIFY RANK(custID) < 1000 AND RANK(custID) > 900
ORDER BY custID;
RANK(field) will (conceptually) retrieve all the rows of the resultset,
order them by the ORDER BY field and assign an incrementing rank ID to them.
QUALIFY allows you to slice that by limiting the rows returned to the qualification expression, which now can legally view the RANKs.
To be clear, I am returning the 900-1000th rows in the query select all from cusotmers,
NOT returning customers with IDs between 900 and 1000.
You can also use the ROW_NUMBER window aggregate on Teradata.
SELECT ROW_NUMBER() OVER (ORDER BY custID) AS RowNum_
, custID
FROM myDatabase.myCustomers
QUALIFY RowNum_ BETWEEN 900 and 1000;
Unlike the RANK windows aggregate, ROW_NUMBER will provide you a sequence regardless of whether the column you are ordering over the optional partition set is unique or not.
Just another option to consider.