Select the 100 lowest values in SQL? - sql

I've been looking around for a while, and it seems it cant be found anywhere. I want to know how do you select the 100 highest and the 100 lowst values in a column? The MIN-function only chooses the lowest one and the MAX the highest one.
Anyone out there who knows how you do this?

SQL Server
Top 100 Highest
SELECT TOP 100 * FROM MyTable
ORDER BY MyCol DESC
Top 100 Lowest
SELECT TOP 100 * FROM MyTable
ORDER BY MyCol ASC
MySQL
Top 100 Highest
SELECT * FROM MyTable
ORDER BY MyCol DESC LIMIT 100
Top 100 Lowest
SELECT * FROM MyTable
ORDER BY MyCol ASC LIMIT 100

You can do it as below,
Highest
select * from
tablename
order by
column DESC
limit 0,100
Lowest
select * from
tablename
order by
column ASC
limit 0,100
EDIT
For SQL Server replace select * from with select TOP 100 * from
The SELECT TOP clause is used to specify the number of records to return.

Use sorting in ascending and descending order and limit output to 100

if you use Sql server
you can order query desc and select top 1000 like :
select top(1000) * from mytable order by value desc

Try this:
DECLARE #V_MaxNo INT;
SELECT #V_MaxNo = COUNT(1) FROM TABLE_NAME WHERE (CONDITION_PART_AS_REQUIRED);
SELECT COLUMN_LIST
FROM (SELECT ROW_NUMBER() OVER (ORDER BY [Order_by_column_list_with_ASC/DESC]) rowNo, COLUMN_LIST
FROM TABLE_NAME) A
WHERE (100 - rowNo) >= 0 or (#V_MaxNo - rowNo) < 100

Here's another approach independent from db engine
MAX
select * from MyTable a where 100 > (select count(id) from MyTable b where a.MyCol <= b.MyCol) order by MyCol desc

Related

I need to limit this query to 1000 records and display the count() in the TOTAL field, how can I do this?

I need to limit the following query to 1000 records and have that number show in the TOTAL column. I can not use fetch as that command occurs after TOTAL is calculated. Is this possible here?
SELECT M.SEQ_NBR,
COUNT(*) OVER() TOTAL,
ROW_NUMBER() OVER(ORDER BY SEQ_NBR DESC) ROWNUMBER
FROM MYTABLE M
ORDER BY ROWNUMBER;
I need line 2 to be something like below, but get
"ORA-00923: FROM keyword not found where expected"
CASE WHEN COUNT(*) < 1000 THEN COUNT(*) ELSE 1000 END OVER() TOTAL,
Thanks for any help you can give.
I believe this is what you are looking for..
select y.*, case when total > 1000 then 1000 else total end total_revamped from
(select x.*,row_number() over (order by null) rownumber,count(1) over () total
from all_source x where 1=1) y
where rownumber <= 1000
order by rownumber
OFFSET 995 ROWS
FETCH NEXT 5 ROWS ONLY
You can replace the table/columns as per your need. Getting the required result in 1 query is quite impossible as you need to first evaluate the records in said table. This is the reason we need to wrap the query into an inner query which does the evaluation for you.
Use a subquery to limit a number of rows to 1000:
SELECT M.SEQ_NBR,
COUNT(*) OVER() TOTAL,
ROW_NUMBER() OVER(ORDER BY SEQ_NBR DESC) ROWNUMBER
FROM (
SELECT * FROM MYTABLE WHERE rownum <= 1000
) M
ORDER BY ROWNUMBER;
I have just connected the dots from your question.
Did not able to understand the issue properly, But I tried following to help you out. -- I have used only 10 rows, You can replace it with 1000.
SELECT
SEQ_NBR,
COUNT(*) OVER() TOTAL
FROM
(
SELECT
M.SEQ_NBR
FROM
MYTABLE M
ORDER BY
SEQ_NBR DESC
FETCH FIRST 10 ROWS ONLY
);
db<>fiddle demo
Cheers!!

SQL query query about selecting particular number of rows

For example -
SELECT * FROM user_names returns about 100 rows.
How would you query to get only row no.30 to row no.40?
Well with MySQL you would do it as follows:
SELECT * FROM user_names LIMIT 30,10
you can use row_number
with CTE_Table
as (SELECT id, ROW_NUMBER() OVER(ORDER BY id DESC) AS Row_Number
FROM dbo.a)
select * from CTE_Table
WHERE Row_Number BETWEEN 30 AND 40
Assuming SQL Server
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY user_names.id) as RowNumber, *
from user_names) un
where un.RowNumber between 30 and 40
replace the ORDER BY clause with whatever you want to order by.

Retrieving the second most highest value from a table

How do I retrieve the second highest value from a table?
select max(val) from table where val < (select max(val) form table)
In MySQL you could for instance use LIMIT 1, 1:
SELECT col FROM tbl ORDER BY col DESC LIMIT 1, 1
See the MySQL reference manual: SELECT Syntax).
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants (except when using prepared statements).
With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
select top 2 field_name from table_name order by field_name desc limit 1
SELECT E.lastname, E.salary FROM employees E
WHERE 2 = (SELECT COUNT(*) FROM employess E2
WHERE E2.salary > E.salary)
Taken from here
This works in almost all Dbs
Select Top 1 sq.ColumnToSelect
From
(Select Top 2 ColumnToSelect
From MyTable
Order by ColumnToSelect Desc
)sq
Order by sq.ColumnToSelect asc
Cool, this is almost like Code Golf.
Microsoft SQL Server 2005 and higher:
SELECT *
FROM (
SELECT
*,
row_number() OVER (ORDER BY var DESC) AS ranking
FROM table
) AS q
WHERE ranking = 2
Try this
SELECT * FROM
(SELECT empno, deptno, sal,
DENSE_RANK() OVER (PARTITION BY deptno ORDER BY sal DESC NULLS LAST) DENSE_RANK
FROM emp)
WHERE DENSE_RANK = 2;
This works in both Oracle and SQL Server.
Try this
SELECT TOP 1 Column FROM Table WHERE Column < (SELECT MAX(Column) FROM Table)
ORDER BY Column DESC
SELECT TOP 1 Column FROM (SELECT TOP <n> Column FROM Table ORDER BY Column DESC)
ORDER BY ASC
change the n to get the value of any position
Maybe:
SELECT * FROM table ORDER BY value DESC LIMIT 1, 1
one solution would be like this:
SELECT var FROM table ORDER BY var DESC LIMIT 1,1

Equivalent of LIMIT and OFFSET for SQL Server?

In PostgreSQL there is the Limit and Offset keywords which will allow very easy pagination of result sets.
What is the equivalent syntax for SQL Server?
This feature is now made easy in SQL Server 2012.
This is working from SQL Server 2012 onwards.
Limit with offset to select 11 to 20 rows in SQL Server:
SELECT email FROM emailTable
WHERE user_id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
ORDER BY: required
OFFSET: optional number of skipped rows
NEXT: required number of next rows
Reference: https://learn.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql
The equivalent of LIMIT is SET ROWCOUNT, but if you want generic pagination it's better to write a query like this:
;WITH Results_CTE AS
(
SELECT
Col1, Col2, ...,
ROW_NUMBER() OVER (ORDER BY SortCol1, SortCol2, ...) AS RowNum
FROM Table
WHERE <whatever>
)
SELECT *
FROM Results_CTE
WHERE RowNum >= #Offset
AND RowNum < #Offset + #Limit
The advantage here is the parameterization of the offset and limit in case you decide to change your paging options (or allow the user to do so).
Note: the #Offset parameter should use one-based indexing for this rather than the normal zero-based indexing.
select top {LIMIT HERE} * from (
select *, ROW_NUMBER() over (order by {ORDER FIELD}) as r_n_n
from {YOUR TABLES} where {OTHER OPTIONAL FILTERS}
) xx where r_n_n >={OFFSET HERE}
A note:
This solution will only work in SQL Server 2005 or above, since this was when ROW_NUMBER() was implemented.
You can use ROW_NUMBER in a Common Table Expression to achieve this.
;WITH My_CTE AS
(
SELECT
col1,
col2,
ROW_NUMBER() OVER(ORDER BY col1) AS row_number
FROM
My_Table
WHERE
<<<whatever>>>
)
SELECT
col1,
col2
FROM
My_CTE
WHERE
row_number BETWEEN #start_row AND #end_row
Specifically for SQL-SERVER you can achieve that in many different ways.For given real example we took Customer table here.
Example 1: With "SET ROWCOUNT"
SET ROWCOUNT 10
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
To return all rows, set ROWCOUNT to 0
SET ROWCOUNT 0
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Example 2: With "ROW_NUMBER and OVER"
With Cust AS
( SELECT CustomerID, CompanyName,
ROW_NUMBER() OVER (order by CompanyName) as RowNumber
FROM Customers )
select *
from Cust
Where RowNumber Between 0 and 10
Example 3 : With "OFFSET and FETCH", But with this "ORDER BY" is mandatory
SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
Hope this helps you.
-- #RowsPerPage can be a fixed number and #PageNumber number can be passed
DECLARE #RowsPerPage INT = 10, #PageNumber INT = 2
SELECT *
FROM MemberEmployeeData
ORDER BY EmployeeNumber
OFFSET #PageNumber*#RowsPerPage ROWS
FETCH NEXT 10 ROWS ONLY
For me the use of OFFSET and FETCH together was slow, so I used a combination of TOP and OFFSET like this (which was faster):
SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Note: If you use TOP and OFFSET together in the same query like:
SELECT TOP 20 columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS
Then you get an error, so for use TOP and OFFSET together you need to separate it with a sub-query.
And if you need to use SELECT DISTINCT then the query is like:
SELECT TOP 20 FROM (SELECT DISTINCT columname1, columname2
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Note: The use of SELECT ROW_NUMBER with DISTINCT did not work for me.
Adding a slight variation on Aaronaught's solution, I typically parametrize page number (#PageNum) and page size (#PageSize). This way each page click event just sends in the requested page number along with a configurable page size:
begin
with My_CTE as
(
SELECT col1,
ROW_NUMBER() OVER(ORDER BY col1) AS row_number
FROM
My_Table
WHERE
<<<whatever>>>
)
select * from My_CTE
WHERE RowNum BETWEEN (#PageNum - 1) * (#PageSize + 1)
AND #PageNum * #PageSize
end
Another sample :
declare #limit int
declare #offset int
set #offset = 2;
set #limit = 20;
declare #count int
declare #idxini int
declare #idxfim int
select #idxfim = #offset * #limit
select #idxini = #idxfim - (#limit-1);
WITH paging AS
(
SELECT
ROW_NUMBER() OVER (order by object_id) AS rowid, *
FROM
sys.objects
)
select *
from
(select COUNT(1) as rowqtd from paging) qtd,
paging
where
rowid between #idxini and #idxfim
order by
rowid;
There is here someone telling about this feature in sql 2011, its sad they choose a little different keyword "OFFSET / FETCH" but its not standart then ok.
The closest I could make is
select * FROM( SELECT *, ROW_NUMBER() over (ORDER BY ID ) as ct from [db].[dbo].[table] ) sub where ct > fromNumber and ct <= toNumber
Which I guess similar to select * from [db].[dbo].[table] LIMIT 0, 10
Elaborating the Somnath-Muluk's answer just use:
SELECT *
FROM table_name_here
ORDER BY (SELECT NULL AS NOORDER)
OFFSET 9 ROWS
FETCH NEXT 25 ROWS ONLY
w/o adding any extra column.
Tested in SQL Server 2019, but I guess could work in older ones as well.
select top (#TakeCount) * --FETCH NEXT
from(
Select ROW_NUMBER() OVER (order by StartDate) AS rowid,*
From YourTable
)A
where Rowid>#SkipCount --OFFSET
#nombre_row :nombre ligne par page
#page:numero de la page
//--------------code sql---------------
declare #page int,#nombre_row int;
set #page='2';
set #nombre_row=5;
SELECT *
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY etudiant_ID ) AS RowNum, *
FROM etudiant
) AS RowConstrainedResult
WHERE RowNum >= ((#page-1)*#nombre_row)+1
AND RowNum < ((#page)*#nombre_row)+1
ORDER BY RowNum
Since nobody provided this code yet:
SELECT TOP #limit f1, f2, f3...
FROM t1
WHERE c1 = v1, c2 > v2...
AND
t1.id NOT IN
(SELECT TOP #offset id
FROM t1
WHERE c1 = v1, c2 > v2...
ORDER BY o1, o2...)
ORDER BY o1, o2...
Important points:
ORDER BY must be identical
#limit can be replaced with number of results to retrieve,
#offset is number of results to skip
Please compare performance with previous solutions as they may be more efficient
this solution duplicates where and order by clauses, and will provide incorrect results if they are out of sync
on the other hand order by is there explicitly if that's what's needed
I assume that, In C# Expression/LINQ statement of skip and take generating below SQL Command
DECLARE #p0 Int = 1
DECLARE #p1 Int = 3
SELECT [t1].[Id]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[Id]
FROM [ShoppingCart] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN #p0 + 1 AND #p0 + #p1
ORDER BY [t1].[ROW_NUMBER]
In SQL server you would use TOP together with ROW_NUMBER()
Since, I test more times this script more useful by 1 million records each page 100 records with pagination work faster my PC execute this script 0 sec while compare with mysql have own limit and offset about 4.5 sec to get the result.
Someone may miss understanding Row_Number() always sort by specific field. In case we need to define only row in sequence should use:
ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
SELECT TOP {LIMIT} * FROM (
SELECT TOP {LIMIT} + {OFFSET} ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ROW_NO,*
FROM {TABLE_NAME}
) XX WHERE ROW_NO > {OFFSET}
Explain:
{LIMIT}: Number of records for each page
{OFFSET}: Number of skip records

What is the simplest SQL Query to find the second largest value?

What is the simplest SQL query to find the second largest integer value in a specific column?
There are maybe duplicate values in the column.
SELECT MAX( col )
FROM table
WHERE col < ( SELECT MAX( col )
FROM table )
SELECT MAX(col)
FROM table
WHERE col NOT IN ( SELECT MAX(col)
FROM table
);
In T-Sql there are two ways:
--filter out the max
select max( col )
from [table]
where col < (
select max( col )
from [table] )
--sort top two then bottom one
select top 1 col
from (
select top 2 col
from [table]
order by col) topTwo
order by col desc
In Microsoft SQL the first way is twice as fast as the second, even if the column in question is clustered.
This is because the sort operation is relatively slow compared to the table or index scan that the max aggregation uses.
Alternatively, in Microsoft SQL 2005 and above you can use the ROW_NUMBER() function:
select col
from (
select ROW_NUMBER() over (order by col asc) as 'rowNum', col
from [table] ) withRowNum
where rowNum = 2
I see both some SQL Server specific and some MySQL specific solutions here, so you might want to clarify which database you need. Though if I had to guess I'd say SQL Server since this is trivial in MySQL.
I also see some solutions that won't work because they fail to take into account the possibility for duplicates, so be careful which ones you accept. Finally, I see a few that will work but that will make two complete scans of the table. You want to make sure the 2nd scan is only looking at 2 values.
SQL Server (pre-2012):
SELECT MIN([column]) AS [column]
FROM (
SELECT TOP 2 [column]
FROM [Table]
GROUP BY [column]
ORDER BY [column] DESC
) a
MySQL:
SELECT `column`
FROM `table`
GROUP BY `column`
ORDER BY `column` DESC
LIMIT 1,1
Update:
SQL Server 2012 now supports a much cleaner (and standard) OFFSET/FETCH syntax:
SELECT [column]
FROM [Table]
GROUP BY [column]
ORDER BY [column] DESC
OFFSET 1 ROWS
FETCH NEXT 1 ROWS ONLY;
I suppose you can do something like:
SELECT *
FROM Table
ORDER BY NumericalColumn DESC
LIMIT 1 OFFSET 1
or
SELECT *
FROM Table ORDER BY NumericalColumn DESC
LIMIT (1, 1)
depending on your database server. Hint: SQL Server doesn't do LIMIT.
The easiest would be to get the second value from this result set in the application:
SELECT DISTINCT value
FROM Table
ORDER BY value DESC
LIMIT 2
But if you must select the second value using SQL, how about:
SELECT MIN(value)
FROM ( SELECT DISTINCT value
FROM Table
ORDER BY value DESC
LIMIT 2
) AS t
you can find the second largest value of column by using the following query
SELECT *
FROM TableName a
WHERE
2 = (SELECT count(DISTINCT(b.ColumnName))
FROM TableName b WHERE
a.ColumnName <= b.ColumnName);
you can find more details on the following link
http://www.abhishekbpatel.com/2012/12/how-to-get-nth-maximum-and-minimun.html
MSSQL
SELECT *
FROM [Users]
order by UserId desc OFFSET 1 ROW
FETCH NEXT 1 ROW ONLY;
MySQL
SELECT *
FROM Users
order by UserId desc LIMIT 1 OFFSET 1
No need of sub queries ... just skip one row and select second rows after order by descending
A very simple query to find the second largest value
SELECT `Column`
FROM `Table`
ORDER BY `Column` DESC
LIMIT 1,1;
SELECT MAX(Salary)
FROM Employee
WHERE Salary NOT IN ( SELECT MAX(Salary)
FROM Employee
)
This query will return the maximum salary, from the result - which not contains maximum salary from overall table.
Old question I know, but this gave me a better exec plan:
SELECT TOP 1 LEAD(MAX (column)) OVER (ORDER BY column desc)
FROM TABLE
GROUP BY column
This is very simple code, you can try this :-
ex :
Table name = test
salary
1000
1500
1450
7500
MSSQL Code to get 2nd largest value
select salary from test order by salary desc offset 1 rows fetch next 1 rows only;
here 'offset 1 rows' means 2nd row of table and 'fetch next 1 rows only' is for show only that 1 row. if you dont use 'fetch next 1 rows only' then it shows all the rows from the second row.
Simplest of all
select sal
from salary
order by sal desc
limit 1 offset 1
select * from (select ROW_NUMBER() over (Order by Col_x desc) as Row, Col_1
from table_1)as table_new tn inner join table_1 t1
on tn.col_1 = t1.col_1
where row = 2
Hope this help to get the value for any row.....
Use this query.
SELECT MAX( colname )
FROM Tablename
where colname < (
SELECT MAX( colname )
FROM Tablename)
select min(sal) from emp where sal in
(select TOP 2 (sal) from emp order by sal desc)
Note
sal is col name
emp is table name
select col_name
from (
select dense_rank() over (order by col_name desc) as 'rank', col_name
from table_name ) withrank
where rank = 2
SELECT
*
FROM
table
WHERE
column < (SELECT max(columnq) FROM table)
ORDER BY
column DESC LIMIT 1
It is the most esiest way:
SELECT
Column name
FROM
Table name
ORDER BY
Column name DESC
LIMIT 1,1
As you mentioned duplicate values . In such case you may use DISTINCT and GROUP BY to find out second highest value
Here is a table
salary
:
GROUP BY
SELECT amount FROM salary
GROUP by amount
ORDER BY amount DESC
LIMIT 1 , 1
DISTINCT
SELECT DISTINCT amount
FROM salary
ORDER BY amount DESC
LIMIT 1 , 1
First portion of LIMIT = starting index
Second portion of LIMIT = how many value
Tom, believe this will fail when there is more than one value returned in select max([COLUMN_NAME]) from [TABLE_NAME] section. i.e. where there are more than 2 values in the data set.
Slight modification to your query will work -
select max([COLUMN_NAME])
from [TABLE_NAME]
where [COLUMN_NAME] IN ( select max([COLUMN_NAME])
from [TABLE_NAME]
)
select max(COL_NAME)
from TABLE_NAME
where COL_NAME in ( select COL_NAME
from TABLE_NAME
where COL_NAME < ( select max(COL_NAME)
from TABLE_NAME
)
);
subquery returns all values other than the largest.
select the max value from the returned list.
This is an another way to find the second largest value of a column.Consider the table 'Student' and column 'Age'.Then the query is,
select top 1 Age
from Student
where Age in ( select distinct top 2 Age
from Student order by Age desc
) order by Age asc
select age
from student
group by id having age< ( select max(age)
from student
)
order by age
limit 1
SELECT MAX(sal)
FROM emp
WHERE sal NOT IN ( SELECT top 3 sal
FROM emp order by sal desc
)
this will return the third highest sal of emp table
select max(column_name)
from table_name
where column_name not in ( select max(column_name)
from table_name
);
not in is a condition that exclude the highest value of column_name.
Reference : programmer interview
Something like this? I haven't tested it, though:
select top 1 x
from (
select top 2 distinct x
from y
order by x desc
) z
order by x
See How to select the nth row in a SQL database table?.
Sybase SQL Anywhere supports:
SELECT TOP 1 START AT 2 value from table ORDER BY value
Using a correlated query:
Select * from x x1 where 1 = (select count(*) from x where x1.a < a)
select * from emp e where 3>=(select count(distinct salary)
from emp where s.salary<=salary)
This query selects the maximum three salaries. If two emp get the same salary this does not affect the query.