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

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.

Related

Oracle select specific rows

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?

How could I query from the first n rows using SQL?

For example, I would like to query from the first 10 rows, how could I achieve that. (Not get the first 10 of the query results).
I tried using 'limit' first then 'where' but it doesn't work.
If I understand correctly you first want to fetch 10 rows of one query, then search within those 10 rows for data. To do that you can use a subquery:
SELECT *
FROM (SELECT *
FROM YOUR_TABLE yt
ORDER BY yt.SOME_COLUMN
LIMIT 10) sq
WHERE sq.SOME_OTHER_COLUMN > 25;
Best of luck.
Based on your sort criteria you can create a SQL like this
SELECT column1, column2, ...
FROM your table
ORDER BY sort column
LIMIT 10
This will give you the top 10 rows from your table based on your sort column

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

Select rows randomly without changing the order in sql query

I searched everywhere to find an SQL query to select rows randomly without changing the order. Almost everyone uses something like this:
SELECT * FROM table WHERE type = 1 ORDER BY RAND() LIMIT 25
But above query changes the order. I need a query which selects randomly among the rows but doesn't changes the order, cause every record has a date also.
Select the random rows and then re-order them:
select t.*
from (select *
from table t
where type = 1
order by rand()
limit 25
) t
order by datecol;
In SQL, if you want rows in a particular order, you need to use an explicit order by clause. You should never depend on the ordering of results with no order by. SQL does not guarantee the ordering. MySQL does not guarantee the ordering, unless the query has an order by.

Keep only N last records in SQLite database, sorted by date

I have an SQLite database that I need to do the following: Keep only last N records, sorted by date. How do you do that?
To delete all but the latest 10 records.
delete
from test
where id not in (
select id
from test
order by date desc
limit 10
)
According to the SQLite documentation:
If SQLite is compiled with the SQLITE_ENABLE_UPDATE_DELETE_LIMIT compile-time option, then the syntax of the DELETE statement is extended by the addition of optional ORDER BY and LIMIT clauses.
(...)
If the DELETE statement has an ORDER BY clause, then all rows that would be deleted in the absence of the LIMIT clause are sorted according to the ORDER BY. The first M rows, where M is the value found by evaluating the OFFSET clause expression, are skipped, and the following N, where N is the value of the LIMIT expression, are deleted. If there are less than N rows remaining after taking the OFFSET clause into account, or if the LIMIT clause evaluated to a negative value, then all remaining rows are deleted.
This would allow you to write:
DELETE FROM table WHERE expr ORDER BY date DESC LIMIT -1 OFFSET 10
to keep only the last 10 records, think inverted.
To delete the older 10 records:
DELETE FROM Table_name
WHERE date in (SELECT date FROM Table_name ORDER BY Date Desc Limit -1
OFFSET (select count(*)-10 from Table_name) );
Let me know how it worked for you!
Assuming you have an id column which is a sequential number (AUTO INCREMENT), you can use the following:
DELETE FROM table_name
WHERE id < (
SELECT MIN(id)
FROM (SELECT id
FROM table_name
ORDER BY id DESC
LIMIT num_of_records_to_keep))
The same query can be used when using a timestamp column (simply replace id with your timestamp column)
I wonder if this is faster or slower than Jackob solution. sqlitebrowser says 0ms for both...
DELETE FROM test WHERE date < ( SELECT date FROM test ORDER BY date DESC LIMIT 1 OFFSET 9 )