SQL HELP: How to get the 2 largest values from the table - sql

I would like to select the top two int values in my table
For example lets say my table looks like this
(Name,Int)
(a,1)
(b,2)
(c,2)
(d,5)
My result query would return
d, b, and c
I am not sure how i would approach this, any suggestions?

2 or 3 values? Question says both???
select top 3 Name
from MyTable
order by IntCol desc
Is this homework? [Note: naming a column 'Int' is a very poor choice. Choose something meaningfull]

It depends on different rdbms.
You can always execute this sql:
select name from tab order by int desc limit 3;
In rdbms like oracle, it becomes more difficult
select * from (
select name from tab order by int
)
where rownum<=3;

Related

When would you use a column name instead of * in a count?

I understand why you use COUNT(*) and COUNT(DISTINCT col), but in which cases would you use simply COUNT(col). Wouldn't COUNT(col) return the same result as COUNT(*)?
SELECT COUNT(CustomerID) AS OrdersFromCustomerID7 FROM Orders
WHERE CustomerID=7;
and
SELECT COUNT(*) AS OrdersFromCustomerID7 FROM Orders
WHERE CustomerID=7;
both result in
OrdersFromCustomerID7
4
in this W3 school example.
When you use COUNT(Colomn) It won't count nulls.
As opposed to COUNT(*) which will count each row individually no matter null or not.
Lets take this case:
ID | NAME
1 John
2 NULL
3 Jonathan
SELECT COUNT(*) FROM Table -- return 3
SELECT COUNT(NAME) FROM Table -- return 2
Try this:
DECLARE #tbl TABLE(ID INT IDENTITY,SomeValue INT);
INSERT INTO #tbl VALUES(1),(2),(NULL);
SELECT *
FROM #tbl
SELECT COUNT(*) AS COUNT_Asterisk
,COUNT(SomeValue) AS COUNT_SomeValue
FROM #tbl
The results vary in cases where column values can be NULL. Both also vary when it comes to performance. You can refer to this article for more details count-vs-countcol
When you count a column that is not NULL, then the following produce the same results:
COUNT(*)
COUNT(1)
COUNT(column)
There is often a small potential difference in performance. The first two count rows. The third actually requires reading the column value (at least in most databases). Under some circumstances, this can require reading additional data to determine if the value is indeed not NULL. This overhead is typically quite small in an aggregation query.
The first, using *, is the original way of counting rows. The second is fine, although I prefer the first. Why? Because COUNT(1) = COUNT(2), and I find that awkward.

How to use max function with select top in sql

I have a table, lets call it TempAccount, with a column named AccountID. It contains numbers from 1,2,3...and so on.
My requirement is that I should select the maximum value from the top 10 AccountIDs.
I know I can do it by creating a temp table and inserting the top 10 values in it and then select the maximum value out of that table. But I was hoping if there is any direct query I can use to achieve this.
Something like MAX(SELECT TOP 10 AccountID FROM TempAccount)
What is the best way I can achieve this?
Note: I am using SQL Server 2012
You can use CTE query. Example:
WITH CTEQuery (AccountId) AS (
SELECT TOP 10 AccountId
FROM TempAccount
ORDER BY AccountId
)
SELECT MAX(AccountId)
FROM CTEQuery
Do the TOP 10 in a derived table, then use MAX on its result. Something like:
select max(dt.col1)
from
(
select top 10 col1
from table
where ...
order by ...
) dt

How to skip the first n rows in sql query

I want to fire a Query "SELECT * FROM TABLE" but select only from row N+1. Any idea on how to do this?
For SQL Server 2012 and above, use this:
SELECT *
FROM Sales.SalesOrderHeader
ORDER BY OrderDate
OFFSET (#Skip) ROWS FETCH NEXT (#Take) ROWS ONLY
https://stackoverflow.com/a/19669165/1883345
SQL Server:
select * from table
except
select top N * from table
Oracle up to 11.2:
select * from table
minus
select * from table where rownum <= N
with TableWithNum as (
select t.*, rownum as Num
from Table t
)
select * from TableWithNum where Num > N
Oracle 12.1 and later (following standard ANSI SQL)
select *
from table
order by some_column
offset x rows
fetch first y rows only
They may meet your needs more or less.
There is no direct way to do what you want by SQL.
However, it is not a design flaw, in my opinion.
SQL is not supposed to be used like this.
In relational databases, a table represents a relation, which is a set by definition. A set contains unordered elements.
Also, don't rely on the physical order of the records. The row order is not guaranteed by the RDBMS.
If the ordering of the records is important, you'd better add a column such as `Num' to the table, and use the following query. This is more natural.
select *
from Table
where Num > N
order by Num
Query: in sql-server
DECLARE #N INT = 5 --Any random number
SELECT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RoNum
, ID --Add any fields needed here (or replace ID by *)
FROM TABLE_NAME
) AS tbl
WHERE #N < RoNum
ORDER BY tbl.ID
This will give rows of Table, where rownumber is starting from #N + 1.
In order to do this in SQL Server, you must order the query by a column, so you can specify the rows you want.
Example:
select * from table order by [some_column]
offset 10 rows
FETCH NEXT 10 rows only
Do you want something like in LINQ skip 5 and take 10?
SELECT TOP(10) * FROM MY_TABLE
WHERE ID not in (SELECT TOP(5) ID From My_TABLE ORDER BY ID)
ORDER BY ID;
This approach will work in any SQL version. You need to stablish some order (by Id for example) so all rows are provided in a predictable manner.
I know it's quite late now to answer the query. But I have a little different solution than the others which I believe has better performance because no comparisons are performed in the SQL query only sorting is done. You can see its considerable performance improvement basically when value of SKIP is LARGE enough.
Best performance but only for SQL Server 2012 and above. Originally from #Majid Basirati's answer which is worth mentioning again.
DECLARE #Skip INT = 2, #Take INT = 2
SELECT * FROM TABLE_NAME
ORDER BY ID ASC
OFFSET (#Skip) ROWS FETCH NEXT (#Take) ROWS ONLY
Not as Good as the first one but compatible with SQL Server 2005 and above.
DECLARE #Skip INT = 2, #Take INT = 2
SELECT * FROM
(
SELECT TOP (#Take) * FROM
(
SELECT TOP (#Take + #Skip) * FROM TABLE_NAME
ORDER BY ID ASC
) T1
ORDER BY ID DESC
) T2
ORDER BY ID ASC
What about this:
SELECT * FROM table LIMIT 50 OFFSET 1
This works with all DBRM/SQL, it is standard ANSI:
SELECT *
FROM owner.tablename A
WHERE condition
AND n+1 <= (
SELECT COUNT(DISTINCT b.column_order)
FROM owner.tablename B
WHERE condition
AND b.column_order>a.column_order
)
ORDER BY a.column_order DESC
PostgreSQL: OFFSET without LIMIT
This syntax is supported, and it is in my opinion the cleanest API compared to other SQL implementations as it does not introduce any new keywords:
SELECT * FROM mytable ORDER BY mycol ASC OFFSET 1
that should definitely be standardized.
The fact that this is allowed can be seen from: https://www.postgresql.org/docs/13/sql-select.html since LIMIT and OFFSET can be given independently, since OFFSET is not a sub-clause of LIMIT in the syntax specification:
[ LIMIT { count | ALL } ]
[ OFFSET start [ ROW | ROWS ] ]
SQLite: negative limit
OFFSET requires LIMIT in that DBMS, but dummy negative values mean no limit. Not as nice as PostgreSQL, but it works:
SELECT * FROM mytable ORDER BY mycol ASC LIMIT -1 OFFSET 1
Asked at: SQLite with skip (offset) only (not limit)
Documented at: https://sqlite.org/lang_select.html
If the LIMIT expression evaluates to a negative value, then there is no upper bound on the number of rows returned.
MySQL: use a huge limit number
Terrible API design, the documentation actually recommends it:
SELECT * FROM tbl LIMIT 1,18446744073709551615;
Asked at: MySQL skip first 10 results
Node.js Sequelize ORM implements it
That ORM allows e.g. findAll({offset: without limit:, and implements workarounds such as the ones mentioned above for each different DBMS.
In Faircom SQL (which is a pseudo MySQL), i can do this in a super simple SQL Statement, just as follows:
SELECT SKIP 10 * FROM TABLE ORDER BY Id
Obviously you can just replace 10 with any declared variable of your desire.
I don't have access to MS SQL or other platforms, but I'll be really surprised MS SQL doesn't support something like this.
DECLARE #Skip int= 2, #Take int= 2
SELECT * FROM TABLE_NAME
ORDER BY Column_Name
OFFSET (#Skip) ROWS FETCH NEXT (#Take) ROWS ONLY
try below query it's work
SELECT * FROM `my_table` WHERE id != (SELECT id From my_table LIMIT 1)
Hope this will help
You can also use OFFSET to remove the 1st record from your query result like this-
Example - find the second max salary from the employee table
select distinct salary from employee order by salary desc limit 1 OFFSET 1
For SQL Server 2012 and later versions, the best method is #MajidBasirati's answer.
I also loved #CarlosToledo's answer, it's not limited to any SQL Server version but it's missing Order By Clauses. Without them, it may return wrong results.
For SQL Server 2008 and later I would use Common Table Expressions for better performance.
-- This example omits first 10 records and select next 5 records
;WITH MyCTE(Id) as
(
SELECT TOP (10) Id
FROM MY_TABLE
ORDER BY Id
)
SELECT TOP (5) *
FROM MY_TABLE
INNER JOIN MyCTE ON (MyCTE.Id <> MY_TABLE.Id)
ORDER BY Id

SQL select column value with biggest number of duplicates

I am having a problem I can't seem to solve. I have a data table that looks like this:
Example:
http://i.stack.imgur.com/tbKEk.png
I need to select the ID_JOB value which is duplicated the most. In this particular example it would be ID_JOB = 1.
Adapt this to your specific SQL implementation. Substitute [job_table] with the table you are querying.
SELECT TOP 1 ID_JOB
FROM job_table
GROUP BY ID_JOB
ORDER BY COUNT(*) DESC
You may need to add more ORDER BY logic in case a count "ties".

how to select first N rows from a table in T-SQL?

Is there any way to select, for example, first 10 rows of a table in T-SQL (working MSSQL)?
I think I saw something in Oracle defined as rownum meta variable, used in a following way
select * from Users where rownum<=10
But what about MSSQL?
select top(#count) * from users
If #count is a constant, you can drop the parentheses:
select top 42 * from users
(the latter works on SQL Server 2000 too, while the former requires at least 2005)
You can use Microsoft's row_number() function to decide which rows to return. That means that you aren't limited to just the top X results, you can take pages.
SELECT *
FROM (SELECT row_number() over (order by UserID) AS line_no, *
FROM dbo.User) as users
WHERE users.line_no < 10
OR users.line_no BETWEEN 34 and 67
You have to nest the original query though, because otherwise you'll get an error message telling you that you can't do what you want to in the way you probably should be able to in an ideal world.
Msg 4108, Level 15, State 1, Line 3
Windowed functions can only appear in the SELECT or ORDER BY clauses.
SELECT TOP 10 *
FROM Users
Note that if you don't specify an ORDER BY clause then any 10 rows could be returned, because "first 10 rows" doesn't really mean anything until you tell the database what ordering to use.
You can also use rowcount, but TOP is probably better and cleaner, hence the upvote for Mehrdad
SET ROWCOUNT 10
SELECT * FROM dbo.Orders
WHERE EmployeeID = 5
ORDER BY OrderDate
SET ROWCOUNT 0
Try this.
declare #topval int
set #topval = 5 (customized value)
SELECT TOP(#topval) * from your_database
SELECT TOP 10 * FROM TABLE_NAME ORDER BY ORDERED_UNIQUE_COLUMN
DESC
ORDERED_UNIQUE_COLUMN could be your incrementing primary key or a timestamp
Try this:
SELECT * FROM USERS LIMIT 10;