Select Top 100 Groups - sql

I have thousands of groups in a table, something like :
1..
1..
2..
2..
2..
2..
3..
3..
.
.
.
10000..
10000..
How can i make a select that give me the Top 3 groups each time.
I Want something like select Top 3 from rows , but it have to return the first three groups not the first three rows.

You can try this :
;with cte as (
select distinct groupId from mytable order by groupid
)
select * from mytable where TheGroupId in (select top 3 groupdid from cte)

You can use DENSE_RANK to assign a number to each group. All members of the same group will have the same number. Then in an outer query, select top 3 groups:
SELECT *
FROM (SELECT *, DENSE_RANK() OVER (ORDER BY id) AS rnk
FROM mytable ) t
WHERE t.rnk <= 3
The above query assumes that id is the column used to group records together.
SQL Fiddle Demo

Use Ranking function Row_Number() :
SELECT *
FROM (SELECT *,
Row_number()
OVER(
partition BY GroupId
ORDER BY GroupId) AS [rn]
FROM YourTable) t
WHERE rn <= 3
Check this MSDN doc for details of all ranking functions.

There is a sql TOP statement that does this
SELECT TOP number|percent column_name(s) FROM table_name;
a description of what it does and how it is used in alternative sql statements for example for mysql and ms access can be found here: http://www.w3schools.com/sql/sql_top.asp
My bad i misread your question, this will return the top rows not groups, could you explain what you are trying to do in more detail?

SELECT *
FROM
(SELECT *
,ROW_NUMBER() OVER (PARTITION BY [Group] ORDER BY [Group] ASC)rn
FROM TableName
)A
WHERE rn <= 3

Related

How to group and pick only certain values based on a field using select query SQL

I have a table as follow
ID
ORDERNO
1
123
1
123
2
456
2
456
During every select query done via application using JDBC, only the grouped records based on ORDERNO should be picked.
That means, for example, during first select query only details related to ID = 1, but we cannot specify the ID number in where clause because we do not know how many number of IDs will be there in future. So the query should yield only one set of records; application will delete those records after picking, hence next select query will result in picking other set of records. How to achieve it?
You can use TOP WITH TIES for this
SELECT TOP (1) WITH TIES
t.ID,
t.ORDERNO
FROM YourTable t
ORDER BY
t.ID;
If you want to select and delete at the same time you could delete using an OUTPUT clause
WITH cte AS (
SELECT TOP (1) WITH TIES
t.ID,
t.ORDERNO
FROM YourTable t
ORDER BY
t.ID
)
DELETE cte
OUTPUT deleted.*;
As one option you could select on the MIN(ID) like:
SELECT *
FROM yourtable
WHERE ID = (SELECT MIN(ID) FROM yourtable);
You could also use window functions to do this:
SELECT ID, ORDERNO
FROM
(
SELECT ID, ORDERNO
DENSE_RANK() OVER (ORDER BY ID ASC) AS dr
FROM yourtable
)dt
WHERE dr = 1;
order your rows and select top n number of rows that you want :
select top (1) with ties ID, ORDERNO
from tablename
order by ID asc

How to use CTE to do recursive for previous row?

I have a problem which I believe can be solve using the CTE.
I create sql query shown below :
with CTE as
(
SELECT Distinct T.testType as name,'tmpRequirement_TestType_Canvas' as template,'n/a' as layout,
0 as x,0 as y,'855' as width,'42' as height,
T.id,T.testType FROM [dbo].[tProperty] P
INNER JOIN tTest_Type T
on P.tTest_Type_id = T.id)
select * from CTE
I got the results like below:
What I would like to get is like shown below :
Basically I would like to have 'y' to be increment by 50 for each row. Is there any way for this?
Thanks in advance.
You need an ordering, but row_number() will do this:
select . . .,
50 * row_number() over (order by ?) as y
from cte;
? is for the column that specifies the ordering.
As your sample from above:
This will start from 0 and Add 50:
select setNumber from
(select setNumber from
(select 50 * ROW_NUMBER() over(order by id) as setNumber from yourTableOrCTE) as a
union all
select 0) as a order by setNumber

Opposite of TOP in SQL Server

I need to retrieve the last few entries from a table. I can retrieve them using:
SELECT TOP n *
FROM table
ORDER BY id DESC
That I looked everywhere and that's the only answer I could find, But that way I get them in reverse order. I need them in the same order as they are in the table because it's for a messaging interface.
Use a derived table:
select id, ...
from
(
select top n id, ...
from t
order by id desc
) dt
order by id
I suggest you to use a ROW_NUMBER() like this:
SELECT *
FROM (
SELECT
*, ROW_NUMBER() OVER (ORDER BY id DESC) AS RowNo
FROM
yourTable
) AS t
WHERE
(RowNO < #n)
ORDER BY
id

SQL Server query for top rows to select with condition

I want to skip first 5 records and then select 10 records
I have a column email in table user. Here I am trying to select top 10 unique rows from table user using this query
select DISTINCT TOP 10 email from user
Now I am trying to select top 10 unique rows from table skipping the first 5 records
select DISTINCT SKIP 5 TOP 10 email from user
which is not done and return error.. can anyone help me
SELECT A.NAME FROM
(SELECT distinct RANK() OVER(ORDER BY NAME) RNK,NAME FROM USERS) A
WHERE A.RNK>4 AND A.RNK<16
Using LIMIT will not guarantee you that you will get top rows with proper order.
If you use ANALYTIC functions, it will give you proper results.
SQL_LIVE_DEMO
Here is one way to do it. I like to use Common Table Expressions for some things like this because it makes the query easy to understand, although this isn't particularly complicated.
WITH CTE AS
(
Select Distinct Email From User
)
,
CTE1 AS
(
Select Email, ROW_NUMBER() over (ORDER BY Email) AS RowNumber
From CTE
)
Select Top 10 * From CTE1 Where RowNumber > 5
with t2 as
(
select t1.*,
row_number() over (order by id) rn
from
(select email, max(id) as id from [user] group by email) as t1
)
select * from t2 where rn between 5 and 10
How about this:
SELECT *
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY email) AS row
FROM user ) a
WHERE row > 5 and row <= 10
I think you are using SKIP incorrectly, it should be part of the ORDER BY clause.
SELECT DISTINCT TOP(10) Email FROM TableName WHERE Email not in (SELECT TOP(5) Email From TableName)
You can try this code, in this query fetch distinct 10 email ids skip 5 records as you say in this question.

Find n largest values in a column

I am trying to find the n largest numbers in a particular column in SQL Server.
We can find the largest value in a column and the 2nd largest value easily.
But how do I find say, 5 largest values in a column ?
You tagged this both for MySQL and SQL Server. In SQL Server you can use TOP:
SELECT TOP 5 yourColumn
FROM yourTable
ORDER BY someColumn DESC;
TOP limits the number of rows returned. To get the data with the largest/smallest values you will want to include an ORDER BY.
In MySQL you will use LIMIT
Another way to do this in SQL Server is using row_number():
select id
from
(
select id, row_number() over(order by id desc) rn
from yourtable
) x
where rn <= 5
See SQL Fiddle With Demo
In MySql you can use [LIMIT {[offset,] row_count }] to do this like so:
...
ORDER BY SomeField DESC
LIMIT #n;
For SQL Server you can use the TOP(n) to get the top n:
SELECT TOP(#n) SomeFieldName
FROM TABLE
ORDER BY SomeField DESC
For example:
SELECT TOP 5 items_sold
FROM tbl_PRODUCT
ORDER BY items_sold dESC
Update: If you have another table families with a foreign key family_ID to products table, and you want to find all products with the top n family id's. Then you can dot this:
SELECT *
FROM Products WHERE family_ID IN
(
SELECT TOP 5 family_ID
FROM families
ORDER BY family_ID DESC
)
Update 2: The topmost product in each family:
;WITH cte
AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY family_ID ORDER BY items_sold DESC) row_num
FROM #Products
)
SELECT * FROM cte
where row_num = 1
Order by family_ID
Here is alive demo
sql server
select min(val)
from your_table
where val in (select top 5 val from your_table order by val desc)
mysql
select min(val)
from your_table
where val in (select val from your_table order by val desc limit 5)