在SQL中选择顶部和选定的行

时间:2014-09-06 23:34:36

标签: c# sql sql-server

我有3000名参赛者。我想要做的只是选择其中的50个,但如果用户不存在于前50个我想要也选择该行并显示其当前位置,下面的查询显示我从主要内部选择前50个位置查询带回所有球员及其位置。现在我想显示当前登录的用户及其位置,那么有什么方法可以通过修改以下内容从子集中选择前50名和用户的条目?即是否可以在像

这样的子集上运行两个选择
SELECT TOP 50 AND SELECT TOP 1 (Where condition)

FROM 
(
    Subset
)

我的查询

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

4 个答案:

答案 0 :(得分:1)

您可以使用union连接两个结果子集:http://msdn.microsoft.com/en-au/library/ms180026.aspx

此外,如果您需要从同一个suset填充结果,那么您可以使用公用表表达式: http://technet.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx

pseodocode:

with subset(...)

select top 50
union
select top 1

答案 1 :(得分:1)

您可以在没有union的情况下执行此操作。您只需要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

这会使用row_number()来执行您希望top执行的操作。我注意到您的问题不包含order by条款,因此我猜您希望按Position进行排序。

答案 2 :(得分:0)

您可以使用CTE而不是子查询和SELECT TOP 50然后选择SELECT TOP 1并将所有类似的东西联合起来....

;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>

答案 3 :(得分:0)

请尝试以下方法:

;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;