从嵌套SQL查询中选择TOP或GROUP BY排名数据

时间:2019-06-19 07:33:04

标签: sql sql-server tsql sql-server-2005

我有一个包含事件和结果以及查询的表,如下所示:

   SELECT T2.EventDate, T2.EventPlace, T2.Par1,
    T2.Par2, T2.Result, T2.ResultEventDate_sum 
    FROM
    (SELECT TOP 15 EventDate, EventPlace, Par1, Par2, 
    Result, SUM(Result) OVER (PARTITION BY EventDate) AS ResultEventDate_SUM
    FROM
        (SELECT EventDate, EventPlace, Par1, Par2, Result, 
                ROW_NUMBER() OVER (PARTITION BY EventDate ORDER BY Result DESC) AS EventDate_rank
        FROM MainTable 
        WHERE AND CAST(UserNb AS int) = 103
              AND Col1 = 'X' AND Result > 0 AND Col2 LIKE '%Y%'
              AND Par1 > 500 AND Par1 <= 700) ranked
    WHERE EventDate_rank <= 5 ORDER BY ResultEventDate_sum DESC) T2

我得到的结果:

EventDate   EventPlace  Par1    Par2    Result  ResultEventDate_SUM
2019-05-26  PLACE nb  1 508      604    51.20   278.11
2019-05-26  PLACE nb  1 508      571    51.68   278.11
2019-05-26  PLACE nb  1 508      249    56.38   278.11
2019-05-26  PLACE nb  1 508       42    59.40   278.11
2019-05-26  PLACE nb  1 508       39    59.45   278.11
2019-06-09  PLACE nb  3 508      449    50.95   217.05
2019-06-09  PLACE nb  3 508      259    54.79   217.05
2019-06-09  PLACE nb  3 508      254    54.89   217.05
2019-06-09  PLACE nb  3 508      178    56.42   217.05
2019-06-16  PLACE nb  4 508      372    51.49   169.56
2019-06-16  PLACE nb  4 508       66    58.51   169.56
2019-06-16  PLACE nb  4 508       20    59.56   169.56
2019-06-02  PLACE nb  2 508      533    50.19   107.46
2019-06-02  PLACE nb  2 508      149    57.27   107.46

我需要从每个事件中获取最多5个结果的最佳(最高)总和的列表,但仅获取3个最佳事件。因此,我将SELECT TOP 15(3个事件乘5个结果)放在一个事件中,当每个事件有5个结果时查询结果就可以了。但是,如果每个事件少于5个结果,我也会从4个事件中得到记录。如何修改查询以确保无论每个结果有多少个事件都只有3个事件?在此示例中,剪切最后2条记录(1个事件的最小结果为107.46)。有没有一种方法可以通过简化查询而不添加其他代码来实现这一目标?

我试图将COUNT(*)放在第一行,但它的计数与col resulteventdate一样,因此我不能将其用作条件。另外,如果我添加为前。存在,该声明太大,需要花费很多时间。

预期结果是一个表,其中只有3个事件的ResultEventDate_sum最好:

EventDate   EventPlace  Par1    Par2    Result  ResultEventDate_SUM
2019-05-26  PLACE nb  1 508      604    51.20   278.11
2019-05-26  PLACE nb  1 508      571    51.68   278.11
2019-05-26  PLACE nb  1 508      249    56.38   278.11
2019-05-26  PLACE nb  1 508       42    59.40   278.11
2019-05-26  PLACE nb  1 508       39    59.45   278.11
2019-06-09  PLACE nb  3 508      449    50.95   217.05
2019-06-09  PLACE nb  3 508      259    54.79   217.05
2019-06-09  PLACE nb  3 508      254    54.89   217.05
2019-06-09  PLACE nb  3 508      178    56.42   217.05
2019-06-16  PLACE nb  4 508      372    51.49   169.56
2019-06-16  PLACE nb  4 508       66    58.51   169.56
2019-06-16  PLACE nb  4 508       20    59.56   169.56

提前感谢您的提示。

测试后更新: 感谢大家。我在查询中测试了您的主张,并且Dense_Rank正确且相当快速地完成了这项工作。对我有很大帮助。

2 个答案:

答案 0 :(得分:1)

您需要再使用一个窗口函数,即Dense_Rank。 这可以帮助您获得所需的输出。

select EventDate,EventPlace,Par1,Par2,Result,ResultEventDate_sum from(
SELECT T2.EventDate, T2.EventPlace, T2.Par1,
T2.Par2, T2.Result, T2.ResultEventDate_sum ,
DENSE_RANK()over(order by ResultEventDate_sum,T2.EventDate desc)rnk
FROM
(SELECT  EventDate, EventPlace, Par1, Par2, 
Result, SUM(Result) OVER (PARTITION BY EventDate) AS ResultEventDate_SUM
FROM
    (SELECT EventDate, EventPlace, Par1, Par2, Result, 
            ROW_NUMBER() OVER (PARTITION BY EventDate ORDER BY Result DESC) AS 
            EventDate_rank
    FROM MainTable 
    WHERE AND CAST(UserNb AS int) = 103
          AND Col1 = 'X' AND Result > 0 AND Col2 LIKE '%Y%'
          AND Par1 > 500 AND Par1 <= 700) ranked
WHERE EventDate_rank <= 5  ) T2
 )T1 
 WHERE RNK<=3

答案 1 :(得分:1)

在以下查询中,我已将EventPlace视为Event_ID。该查询将返回TOP 3事件(基于每个事件的结果总和)详细信息(每个事件的TOP 5行)

settings.gradle