2

我有两个具有以下架构的表:

表 A

usernName, email (one email per user)

表 B

userName, product (many products per user)

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

我预先验证有超过30条记录(避免重复)

我知道groupby帮不了我。我应该使用 rankpartitionby吗?groupby和 和有什么不一样partitionby

我该怎么写这个?

4

2 回答 2

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
于 2012-05-20T07:32:18.957 回答
1

以下内容在逻辑上应该等同于@Quassnoi 的建议,但其构建方式使您能够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
;
于 2012-05-20T17:48:15.153 回答