从集合中获取 "category" 前几行

Get top rows by "category" from a collection

我正在使用 Couchbase 和 N1QL。

假设我有 table 种产品。产品具有 categoryIdprice 以及其他属性:

id name categoryId price
1 product 1 cat1 5
2 product 2 cat2 100
3 product 3 cat1 25

我知道如何获取单个类别中最昂贵的 5 个产品。我会做这样的事情:

SELECT * FROM products
WHERE categoryId = 'cat1'
ORDER BY price DESC
LIMIT 5

但是我如何查询每个类别前 5 个最昂贵的产品?我知道我可以做 WHERE categoryId IN ['cat1', 'cat2'],但这会导致这些类别中的前 5 名产品,而不是每个类别

有 couchbase 或 N1QL 专家可以帮助我吗?

提前致谢!

使用WINDOW 函数

SELECT p1.*, MISSING AS r
FROM (SELECT p.*, 
      RANK() OVER (PARTITION BY p.categoryId ORDER BY p.price DESC) AS r
      FROM products AS p
      WHERE p.categoryId IS NOT NULL) AS p1
WHERE p1.r < 6;

Non-Window 函数(UNNEST 应该表现更好)

CREATE INDEX ix1 ON products(categoryId, price DESC);

SELECT p2.*, MISSING AS r
FROM (SELECT p.*,
      (SELECT RAW 1+COUNT(1)
       FROM products AS p1
       WHERE p1.categoryId = p.categoryId AND p1.price > p.price)[0] AS r
      FROM products AS p
      WHERE p.categoryId IS NOT NULL) AS p2
WHERE p2.r < 6;

OR

SELECT u.*
FROM (SELECT DISTINCT RAW p.categoryId
      FROM products AS p
      WHERE p.categoryId IS NOT NULL) AS c
UNNEST (SELECT p1.*
    FROM products AS p1
    WHERE p1.categoryId = c
    ORDER BY p1.categoryId, p1.price DESC
    LIMIT 5) AS u;

OR

WITH categoryIds AS (SELECT DISTINCT RAW p.categoryId
                     FROM products AS p
                     WHERE p.categoryId IS NOT NULL)
SELECT c AS categoryId,
       (SELECT p1.*
        FROM products AS p1
        WHERE p1.categoryId = c
        ORDER BY p1.categoryId, p1.price DESC
        LIMIT 5) AS top5
FROM categoryIds AS c ;