每种类型记录的SQL Server示例

时间:2011-02-22 19:21:55

标签: sql sql-server tsql greatest-n-per-group

我有一个包含各个学期记录的表格,我想要一个查询来选择每个学期的前5行。

我想要一个按键字段(序列)排序的结果集和一个在每个学期内随机排序的结果集。

表格如下:

  • serial int
  • 学期char(4)
  • grade int

表格数据:

Semester|Serial|NewSerial
SP10    |1     |1001
SP10    |2     |1002
SP10    |3     |1003
SP10    |4     |1004
SP10    |5     |1005
SP10    |6     |1006
SP10    |7     |1007
SP10    |8     |1008
SP10    |9     |1009
SP10    |10    |1010
FA10    |1     |2001
FA10    |2     |2002
FA10    |3     |2003
FA10    |4     |2004
FA10    |5     |2005
FA10    |6     |2006
FA10    |7     |2007
FA10    |8     |2008
FA10    |9     |2009
FA10    |10    |2010
FA09    |1     |3001
FA09    |2     |3002
FA09    |3     |3003
FA09    |4     |3004
FA09    |5     |3005
FA09    |6     |3006
FA09    |7     |3007
FA09    |8     |3008
FA09    |9     |3009
FA09    |10    |3010

结果1:按序列排序,前5名

Semester|Serial|NewSerial
SP10    |1     |1001
SP10    |2     |1002
SP10    |3     |1003
SP10    |4     |1004
SP10    |5     |1005
FA10    |1     |2001
FA10    |2     |2002
FA10    |3     |2003
FA10    |4     |2004
FA10    |5     |2005
FA09    |1     |3001
FA09    |2     |3002
FA09    |3     |3003
FA09    |4     |3004
FA09    |5     |3005

结果2:在学期内随机排序(抽样)

Semester|Serial|NewSerial
SP10    |3     |1003
SP10    |1     |1001
SP10    |5     |1005
SP10    |2     |1002
SP10    |4     |1004
FA10    |2     |2002
FA10    |1     |2001
FA10    |4     |2004
FA10    |3     |2003
FA10    |5     |2005
FA09    |3     |3003
FA09    |1     |3001
FA09    |2     |3002
FA09    |5     |3005
FA09    |4     |3004

3 个答案:

答案 0 :(得分:5)

这些应该这样做:

WITH [query_semester] AS (
    SELECT RN = ROW_NUMBER() OVER (PARTITION BY semester
    ORDER BY serial),
    serial, semester, grade
    FROM SemesterTable)
SELECT serial, semester, grade
FROM [query_semester] WHERE [RN] <= 5;

和随机的一个:

WITH [query_semester] AS (
    SELECT RN = ROW_NUMBER() OVER (PARTITION BY semester
    ORDER BY NEWID()),
    serial, semester, grade
    FROM SemesterTable)
SELECT serial, semester, grade
FROM [query_semester] WHERE [RN] <= 5;

答案 1 :(得分:0)

向我们展示一些样本数据和预期结果。

您需要选择TOP TOP 5 您还需要GROUP BY学期类型(如果这是一个日期,那么就是这样)。

而不是TOP 5使用HAVING计数...

答案 2 :(得分:0)

不知道你用什么标准来组成新系列,但是如果它只需要按学期连续递增(在千位),那么

select semester, serial,
    newserial = (DENSE_RANK() over (order by semester) * 1000) + rn
from
(   select *, rn=ROW_NUMBER() over (partition by semester order by serial)
    from tbl
) x
where rn <= 5
order by semester

按顺序排序。为order by serial交换order by newid()以获得随机抽样。

注意:

  1. 兼容级别为90 +的SQL Server 2005+
  2. newserial的公式很好,因为每个学期只能有5个项目,所以不会出现冲突问题
  3. 修改

    这个问题似乎反直觉,但如果newserial只是一个常规字段(未列出),则选择部分变得简单

    select semester, serial, newserial