Display every 3rd record in table - c#

I have a table which contains 30 rows I want to display every 3rd record in that table in the same order I'm using row_number but order changed .
Select * from (select *,rn=row_number()
over(order by name)
from employee_030)x
where rn%5=0
It will get order by name,.
I want records without using order by clause.

You can use ORDER BY (SELECT 0) as follows
Select * from (select *,rn=row_number()
over(ORDER BY (SELECT 0))
from employee_030)x
where rn%3=0

Related

How to use limit the results returned from SQL Server using ROW_NUMBER()

I have database as below
CREATE DATABASE Test2;
CREATE TABLE table1
(
name nvarchar(50),
year int,
total1 int,
total2 int
);
INSERT INTO table1 (name, year, total1,total2)
VALUES ('a', 2020, 25,3);
INSERT INTO table1 (name, year, total1,total2)
VALUES ('b', 2018, 33,4);
INSERT INTO table1 (name, year, total1,total2)
VALUES ('c', 2020, 10,3);
INSERT INTO table1 (name, year, total1,total2)
VALUES ('b', 2018, 7,2);
INSERT INTO table1 (name, year, total1,total2)
VALUES ('a', 2020, 20,6);
I want to limit the results returned from SQL Server (take 2nd row and 3rd row) with this code
select
*
from
(select
year, name,
sum(total1) as "sum_Total1",
sum(total2) as "sum_Total2",
round((cast(isnull(sum(total2), 0) as float)) / (cast(sum(total1) as float)), 3) as "sum_Total2/sum_Total1",
row_number() over (order by round((cast(isnull(sum(total2), 0) as float)) / (cast(sum(total1) as float)), 3) asc) as no
from
Table_1
group by
name, year
order by
round((cast(isnull(sum(total2), 0) as float)) * 100 / (cast(sum(total1) as float)), 3) asc) a
where
a.no > 1 and a.no < 3
SQL Server return an error:
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
Actually since you have already used the Order By in this line ROW_NUMBER() over(ORDER BY ROUND you don't need to use it again in your inner query after grouping. So all that you need to do is removing the unnecessary order by after your group by keyword.
Also FYI, I can see that you've queried from Table_1 while your table name is table1, so you need to fix it as well.
there are two issues:
You are not using the same table which you created.
to get the 2nd and 3rd row, you'll need to change the condition a.no < 3 to a.no <= 3
there is no use of order by clause as we have no.
Finally:
SELECT *
FROM
(
SELECT year,
name,
SUM(total1) AS "sum_Total1",
SUM(total2) AS "sum_Total2",
ROUND((CAST(ISNULL(SUM(total2), 0) AS FLOAT)) / (CAST(SUM(total1) AS FLOAT)), 3) AS "sum_Total2/sum_Total1",
ROW_NUMBER() OVER(
ORDER BY ROUND((CAST(ISNULL(SUM(total2), 0) AS FLOAT)) / (CAST(SUM(total1) AS FLOAT)), 3) ASC) AS no
FROM Table1
GROUP BY name,
year
--ORDER BY ROUND((CAST(ISNULL(SUM(total2), 0) AS FLOAT)) * 100 / (CAST(SUM(total1) AS FLOAT)), 3) ASC
) a
WHERE a.no > 1
AND a.no <= 3;
Just move the order by outside your subquery:
select *
from
(
select year ,name,
sum(total1) as "sum_Total1",
SUM(total2) as "sum_Total2",
ROUND((CAST(ISNULL(sum(total2),0) as float))/
(CAST(sum(total1) as float)),3) as "sum_Total2/sum_Total1",
ROW_NUMBER() over (ORDER BY
ROUND((CAST(ISNULL(sum(total2),0) as float))/ (CAST(sum(total1) as float)),3) ASC ) as no
from Table1
group by name, year
) a
where a.no > 1 and a.no < 4
order by no;

Entity Framework SqlQuery not returning row_number() value

I have a SELECT statement that returns row_number() value with all other fields from table. Query is pretty simple and is working in SSMS:
SELECT
*, CAST(ROW_NUMBER() OVER(ORDER BY TablePrimaryKey) AS INT) AS [RowNumber]
FROM
TableName
WHERE
TablePrimaryKey > 10
(In real application WHERE statement is much more complex, but for simplicity I put it like this)
In my project I created a POCO class that contains RowNumber property (with all other necessary properties)
...
public int RowNumber { get; set; }
...
And I made sure migrations won't create additional columns in table at my entityConfiguration class:
this.Ignore(x => x.RowNumber);
Problem is that with Entity Framework's SqlQuery() method it returns all columns from the table as it should, but RowNumber is always 0. I'm using Entity Framework 6.1 version. Did I miss something, or can this not be done this way?
This is to answer your question in comment.
WITH main AS ( SELECT * ,ROW_NUMBER() OVER(ORDER BY PrimaryKeyId) AS
'RowNumber' FROM [TableName] WHERE [month] = 10 AND [year] = 2014 )
SELECT * FROM main WHERE RowNumber = 2
C#/EF code:
int RowNumber = 2;
var row = TableName.OrderBy(t=>t.PrimaryKeyId).Skip(RowNumber -1).Take(1);
The SQL generated looks like:
DECLARE #p0 Int = 1
DECLARE #p1 Int = 1
SELECT [t1].[ID], [t1].c1 FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ID]) AS [ROW_NUMBER],
[t0].[ID], [t0].c1
FROM [TableName] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN #p0 + 1 AND #p0 + #p1
ORDER BY [t1].[ROW_NUMBER]
I am using Linq-to-SQL, EF should be similar: the sorting is on server side, and it returns 1 record only.

select top and a selected row in SQL

I have a league with 3000 entrants. What I want to do is select only 50 of these but if the user does not exist in this top 50 I want to select that row also and display their current position, the below query shows I am selecting the top 50 positions from the main inner query which brings back all players and their positions. Now I want to show the current logged in user and their position so is there any way to select top 50 and the user's entry from the subset by amending the below? I.e. is it possible to run two selects on a subset like
SELECT TOP 50 AND SELECT TOP 1 (Where condition)
FROM
(
Subset
)
my Query
SELECT TOP 50 [LeagueID],
[EntryID],
[UserID],
[TotalPoints],
[TotalBonusPoints],
[TotalPointsLastEvnet],
[TotalBonusPointsLastRaceEvent],
[Prize],
[dbo].[GetTotalPool]([LeagueID]) AS [TotalPool],
DENSE_RANK() OVER( PARTITION BY [LeagueID] ORDER BY [TotalPoints] DESC, [TotalBonusPoints] DESC) AS [Position],
DENSE_RANK() OVER( PARTITION BY [LeagueID] ORDER BY [TotalPointsLastRace] DESC, [TotalBonusPointsLastRace] DESC) AS [PositionLastRace]
FROM
(
// inner query here bringing back all entrants
) AS DATA
You can use union for joining two subset of results: http://msdn.microsoft.com/en-au/library/ms180026.aspx
Also if you need to populate result from same suset then you can use common table expression:
http://technet.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx
The pseodocode:
with subset(...)
select top 50
union
select top 1
You can do this without a union. You just need or:
WITH data as (
// inner query here bringing back all entrants
)
SELECT * -- or whatever columns you really want
FROM (SELECT data.*
DENSE_RANK() OVER (PARTITION BY [LeagueID]
ORDER BY [TotalPoints] DESC, [TotalBonusPoints] DESC
) AS [Position],
DENSE_RANK() OVER (PARTITION BY [LeagueID]
ORDER BY [TotalPointsLastRace] DESC, [TotalBonusPointsLastRace] DESC
) AS [PositionLastRace],
ROW_NUMBER() OVER (PARTITION BY [LeagueID]
ORDER BY [TotalPoints] DESC, [TotalBonusPoints] DESC
) as Position_Rownum
FROM data
) d
WHERE Position_RowNum <= 50 or UserId = #Current_userid
This uses row_number() to do what you wanted top to do. I note that your question does not include an order by clause, so I am guessing that you want the ordering by Position.
You can use a CTE instead of sub-query and SELECT TOP 50 and then SELECT TOP 1 and union all something like this....
;WITH CTE AS
(
// inner query here bringing back all entrants
)
SELECT TOP 50 * FROM CTE WHERE <Some Codition>
UNION ALL
SELECT TOP 1 * FROM CTE WHERE <Some other Codition>
Please try the following:
;WITH entrants
([LeagueID],[EntryID],[UserID],[TotalPoints],[TotalBonusPoints],[TotalPointsLastEvnet],
[TotalBonusPointsLastRaceEvent],[Prize],[TotalPool],[Position],[PositionLastRace])
AS
(
SELECT [LeagueID],
[EntryID],
[UserID],
[TotalPoints],
[TotalBonusPoints],
[TotalPointsLastEvnet],
[TotalBonusPointsLastRaceEvent],
[Prize],
[dbo].[GetTotalPool]([LeagueID]) AS [TotalPool],
DENSE_RANK() OVER( PARTITION BY [LeagueID] ORDER BY [TotalPoints] DESC, [TotalBonusPoints] DESC) AS [Position],
DENSE_RANK() OVER( PARTITION BY [LeagueID] ORDER BY [TotalPointsLastRace] DESC, [TotalBonusPointsLastRace] DESC) AS [PositionLastRace]
FROM
(
// inner query here bringing back all entrants
) AS DATA
)
SELECT TOP 50 * FROM entrants
UNION
SELECT * FROM entrants WHERE UserID = #current_userid
ORDER BY Position;

SQL + ASP.Net Efficient paging

My method of paging is inefficient as it calls the same query twice therefore doubling the query time. I currently call the 1 query that joins about 5 tables together with XML search querys to allow for passing List from ASP.net.. then I need to call exactly the same query except with a Count(row) to get the amount of records
For Example (I have removed bits to make it easier to read)
Main Query:
WITH Entries AS (
select row_number() over (order by DateReady desc)
as rownumber, Columns...,
from quote
join geolookup as Pickup on pickup.geoid = quote.pickupAddress
where
quote.Active=1
and //More
)
select * from entries
where Rownumber between (#pageindex - 1) * #pagesize + 1 and #pageIndex * #pageSize
end
Count Query:
select count(rowID)
from quote
join geolookup as Pickup on pickup.geoid = quote.pickupAddress
where
quote.Active=1
and //More
)
You could select the results of your big query into a temp table, then you could query this table for the row number and pull out the rows you need.
To do this, add (after your select statement and before the from)
INTO #tmpTable
Then reference your table as #tmpTable
select row_number() over (order by DateReady desc)
as rownumber, Columns...,
into #tmpTable
from quote
join geolookup as Pickup on pickup.geoid = quote.pickupAddress
where
quote.Active=1
and //More
)
SELECT #Count = COUNT(*) FROM #tmpTable
select * from #tmpTable
where Rownumber between (#pageindex - 1) * #pagesize + 1 and #pageIndex * #pageSize
You can set an output parameter which will hold the number of rows from the first query.
You could do something like
WITH Entries AS (
select row_number() over (order by DateReady desc)
as rownumber, Columns...,
from quote
join geolookup as Pickup on pickup.geoid = quote.pickupAddress
where
quote.Active=1
and //More
)
select #rowcount = max(rownumber) from entries
select * from entries
where Rownumber between (#pageindex - 1) * #pagesize + 1 and #pageIndex * #pageSize
Hope this helps

How to create t-sql to load next n-amount of records?

I need an example of creating t-sql query to load next 10 records (depends on the default row amount in grid).
the same kind of linq has to skip rows.
So for example I have 100K of results I need to load just 10 between 100 and 110 records and so on. The idea is to make it page load very fast
I need also to build paging for my grid so I need to know how many records in total
In MS SQL 2005/2008 you can do something like this
with cte
as
(
select row_number() over (order by ID) RowNumber, *
from MyTable
)
select *
from cte
where RowNumber between 10 and 20
[Edit]
With total count column
select *
from
(
select
row_number() over (order by ID) RowNumber,
count(*) over() TotalRowCount,
*
from MyTable
) tt
where RowNumber between 10 and 20
Try this
SELECT YourColumn1, YourColumn2, RN
FROM
(
SELECT YourTable1.*, ROW_NUMBER() OVER (ORDER BY YourTable1PK) RN
FROM YourTable1
) sq
WHERE sq.rn BETWEEN 10 AND 20
You can use a query like this. It should be fast as long as you have an index on the Records.Id column.
select *
from
(select
row_number() over (order by Id) as [RowNum],
count(*) over() as [TotalCount],
Id from #Records) as R
where
[RowNum] between #StartRow and (#StartRow + #PageSize)
Check out MSDN to find out more about the ROW_NUMBER() function.

Categories

Resources