如何在按计数排序的sql表中获得10个中级用户

时间:2012-05-20 07:21:42

标签: sql sql-server sql-server-2008

我有两个包含以下架构的表:

表A

usernName, email (one email per user)

表B

userName, product (many products per user)

我想写一个查询,返回产品数量最多的10个用户的userName + email,中间的10个用户和10个产品数量最少的用户。

我事先确认有超过30条记录(以避免重复)

我知道groupby不会帮助我。我应该使用partitionby等级吗? groupbypartitionby之间有什么区别?

我该怎么写呢?

2 个答案:

答案 0 :(得分:4)

SELECT  userName, email
FROM    (
        SELECT  *,
                ROW_NUMBER() OVER (ORDER BY products DESC) rn,
                COUNT(*) OVER () AS cnt
        FROM    (
                SELECT  userName, email, products
                FROM    a
                CROSS APPLY
                        (
                        SELECT  COUNT(*) products        
                        FROM    b
                        WHERE   b.userName = a.userName
                        ) p
                )
        ) q
WHERE   rn <= 10
        OR
        rn >= cnt - 10
        OR
        rn BETWEEN cnt / 2 - 5 AND cnt / 2 + 4

答案 1 :(得分:1)

以下应该在逻辑上等同于@Quassnoi's suggestion,但其构建方式使您能够轻松地对10进行参数化(在下面用@cnt替换):

SELECT
  userName,
  email
FROM (
  SELECT
    A.userName,
    A.email,
    rnAsc    = ROW_NUMBER() OVER (ORDER BY COUNT(*) ASC),
    rnDesc   = ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC)
  FROM A
    INNER JOIN B ON A.userName = B.userName
  GROUP BY
    A.userName,
    A.email
) s
WHERE rnAsc  <= @cnt
   OR rnDesc <= @cnt
   OR rnAsc - rnDesc BETWEEN -@cnt AND @cnt - 1
;