Как получить «топ X с остальными» в SQL? - PullRequest
4 голосов
/ 17 сентября 2010

Допустим, у меня есть таблица со столбцами «имя» и «количество», и я хочу получить первые X продуктов, которые являются наиболее представленными, и еще одну строку, которая является суммой всех других продуктов.

Мы можем взять этот пример сценария SQL в качестве примера:

CREATE TEMPORARY TABLE product
(
    name TEXT,
    quantity INT
);

INSERT INTO product (name, quantity)
VALUES
    ('carrot', 5),
    ('tomato', 1),
    ('potato', 3),
    ('grape', 8),
    ('salad', 10);

Из этого набора образцов я хочу получить такой результат:

name    quantity
----------------
salad   10
grape   8
others  9

В настоящее время я использую следующее решение, но мне интересно, есть ли что-нибудь более красивое и / или более эффективное:

WITH top AS (
      SELECT name, 
             quantity
        FROM product
    ORDER BY quantity DESC
    LIMIT 2),
     without AS (
      SELECT 'others' AS other, 
             sum(product.quantity) AS quantity
        FROM product
       WHERE product.name NOT IN (SELECT name FROM top)
    GROUP BY other)
SELECT name, quantity
  FROM (SELECT name, quantity
          FROM top
        UNION
        SELECT other, quantity
          FROM without) AS t
ORDER BY quantity DESC;

1 Ответ

4 голосов
/ 17 сентября 2010

Использование:

WITH summary AS (
    SELECT p.*,
           ROW_NUMBER() OVER (ORDER BY p.quantity DESC) AS rank
      FROM PRODUCT p)
  SELECT s.name, 
         s.quantity, 
         s.rank
    FROM summary s
   WHERE s.rank <= 2
UNION ALL
  SELECT 'other', 
         SUM(t.quantity), 
         3
    FROM summary t
   WHERE t.rank > 2
ORDER BY rank, quantity DESC

Относительно UNION

Если вам нужно удалить дубликаты, используйте UNION.В противном случае используйте более быструю альтернативу, UNION ALL, чтобы объединить запросы с совпадающими типами данных в позиции в предложении SELECT, не удаляя дубликаты (и быстрее для этого).

Не используйте производную таблицу / встроенныйПросмотр, если вам не нужно

Это:

SELECT name, quantity
 FROM (SELECT name, quantity
         FROM top
       UNION
      SELECT other, quantity
        FROM without) AS t
ORDER BY quantity DESC;

.. нужно только:

SELECT name, quantity
  FROM top
UNION
SELECT other, quantity
  FROM without
ORDER BY quantity DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...