How to select first-n/top-n rows from a query's resultant if its count is more than a given number? - sql

I have a query that returns more than 1000 rows.
Step1:
with total_res as (
select table1.col1, table1.col2, table2.col3,... table2.coln
from table1 join table2
on table1.keycol=table2.keycol
where table1.col4='ABCD' and table2.col5 <= '02-02-2022'
order by table1.col1 desc)
In my requirement, I have to return the first 350rows by ordering col3 in desc if the output of the above query contain more than 1000rows.
So I added a row number column like below to add sequential numbers to the resulset from above.
Step2:
select col1, col2, col2...coln, ROW_NUMBER() OVER (ORDER BY col3 desc) as number from total_res;
What I don't understand now is how can I check if the output from step2 contains more than 350 rows and if so, select the first 350 rows.
Could anyone let me know how can I achieve this ? Or is there a better way to do it than using row_number ?

try like below in 2nd step check highest number>350 and then limit the value 350
with cte as
(
select col1, col2, col2...coln, ROW_NUMBER() OVER (ORDER BY col3 as number from total_res
) select * from cte
where 350 < ( select max(number) from cte)
order by number
limit 350

Related

Hive / SQL query for top n values per key

I want top 2 valus per key. The result would look like:
What should be the hive query.
You can use a window function with OVER() close:
select col1,col2 from (SELECT col1,
col2,
ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2 DESC) AS row_num
FROM data)f
WHERE f.row_num < 3
order by col1,col2

Rows between rownumber 1-2 million from an oracle table without field rownum in final output?

How to get rows between row number 1 million to 2 million from an oracle table without having field rownum in final output?
Just do:
select col1, col2, col3, . . .
from (select t.*, rownum as seqnum
from t
) t
where seqnum between 100000 and 200000;
That is, select the columns that you want in the output.

Returning a certain number of results from the top

How do I return a certain number of rows, that are a certain number of rows from the top of a SELECT query?
What I mean is, suppose I had a table with 1000 rows. Suppose I want the first 50 rows, then I want the second 50 rows, then the third 50 rows, and so on. I know that TOP or LIMIT will limit the number of rows that are returned, but I am unsure how to tell SQL to get me the rows from a certain point in the returned table.
In Sql server you can make use of ROW_NUMBER() function to do thing you want
SELECT ROW_NUMBER() OVER(ORDER BY col3 DESC) AS Row,
col1, col2, col3
FROM tablename
in short
WITH ctetable AS
(
SELECT ROW_NUMBER() OVER(ORDER BY col3 DESC) AS RowNumber ,
col1, col2, col3
FROM tablename
)
SELECT *
FROM ctetable
WHERE RowNumber BETWEEN 1 AND 50;
SELECT TOP 50 * FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY ID DESC) AS [Index], * FROM MyTable
) AS A
WHERE A.[Index] BETWEEN #StartIndex AND #EndIndex
;With CTE as(SELECT ROW_NUMBER() OVER(ORDER BY (select 0)) AS rno, * FROM MyTable)
select * from CTE where rno between start and end;

Multiple rows match, but I only want one?

Sometimes I wish to perform a join whereby I take the largest value of one column. Doing this I have to perform a max() and a groupby- which prevents me from retrieving the other columns from the row which was the max (beause they were not contained in a GROUP BY or aggregate function).
To fix this, I join the max value back on the original data source, to get the other columns. However, my problem is that this sometimes returns more than one row.
So, so far I have something like:
SELECT * FROM
(SELECT Col1, Max(Col2) FROM Table GROUP BY Col1) tab1
JOIN
(SELECT Col1, Col2 FROM Table) tab2
ON tab1.Col2 = tab2.Col2
If the above query now returns three rows (which match the largest value for column2) I have a bit of a headache.
If there was an extra column- col3 and for the rows returned by the above query, I only wanted to return the one which was, say the minimum Col3 value- how would I do this?
If you are using SQL Server 2005+. Then you can do it like this:
CTE way
;WITH CTE
AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2 DESC) AS RowNbr,
table.*
FROM
table
)
SELECT
*
FROM
CTE
WHERE
CTE.RowNbr=1
Subquery way
SELECT
*
FROM
(
SELECT
ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2 DESC) AS RowNbr,
table.*
FROM
table
) AS T
WHERE
T.RowNbr=1
As I got it can be something like this
SELECT * FROM
(SELECT Col1, Max(Col2) FROM Table GROUP BY Col1) tab1
JOIN
(SELECT Col1, Col2 FROM Table) tab2
ON tab1.Col2 = tab2.Col2 and Col3 = (select min(Col3) from table )
Assuming you are using SQL-Server 2005 or later You can make use of Window functions here. I have chosen ROW_NUMBER() but it is not hte only option.
;WITH T AS
( SELECT *,
ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2 DESC) [RowNumber]
FROM Table
)
SELECT *
FROM T
WHERE RowNumber = 1
The PARTITION BY within the OVER clause is equivalent to your group by in your subquery, then your ORDER BY determines the order in which to start numbering the rows. In this case Col2 DESC to start with the highest value of col2 (Equivalent to your MAX statement).

How can I get the n-th row in the Query results?

How can I get the n-th row of a TSQL query results?
Let's say, I want to get the 2nd row of this SELECT:
SELECT * FROM table
ORDER BY 2 ASC
What version of SQL Server are you targeting? If 2005 or greater, you can use ROW_NUMBER to generate a row number and select using that number. http://msdn.microsoft.com/en-us/library/ms186734.aspx
WITH orderedtable AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY <your order here>) AS 'RowNumber'
FROM table
)
SELECT *
FROM orderedtable
WHERE RowNumber = 2;
You can use a trick combining TOP with ORDER BY ASC/DESC to achieve an effect similar to MySQL's LIMIT:
SELECT TOP 2 * INTO #temptable FROM table
ORDER BY 2 ASC
SELECT TOP 1 * FROM #temptable
ORDER BY 2 DESC
or without temptable, but nested statements:
SELECT TOP 1 * FROM
(
SELECT TOP 2 * FROM table
ORDER BY 2 ASC
) sub
ORDER BY 2 DESC
The first time you select all rows up to the one you want to actually have, and in the second query you select only the first of the remaining when ordering them reversely, which is exactly the one you want.
Source: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=850&lngWId=5
One way;
;with T(rownumber, col1, colN) as (
select
row_number() over (order by ACOLUMN) as rownumber,
col1,
colN
from
atable
)
select * from T where rownumber = 2