我有两个包含以下架构的表:
表A
usernName, email (one email per user)
表B
userName, product (many products per user)
我想写一个查询,返回产品数量最多的10个用户的userName + email
,中间的10个用户和10个产品数量最少的用户。
我事先确认有超过30条记录(以避免重复)
我知道groupby
不会帮助我。我应该使用partitionby
等级吗?
groupby
和partitionby
之间有什么区别?
我该怎么写呢?
答案 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
;