SQL показывает первое и последнее значение в подсчете - PullRequest
0 голосов
/ 01 мая 2019

Мне нужно написать запрос, показывающий максимальное и минимальное количество заказов для заказа клиента.

Я пытался:

(SELECT TOP 1 CustomerID, COUNT(*) AS Number_Of_Orders
FROM Orders
GROUP BY CustomerID
ORDER BY COUNT(*) ASC)

UNION ALL

(SELECT TOP 1 CustomerID, COUNT(*) AS Number_Of_Orders
FROM Orders
GROUP BY CustomerID
ORDER BY COUNT(*) DESC)

Но мне не удалось объединить вывод, я получил ошибку Incorrect syntax near the keyword 'ORDER'.

Как мне это получить?

Ответы [ 3 ]

5 голосов
/ 01 мая 2019

Я не уверен, что хотел бы запустить агрегацию дважды, поэтому используйте оконные функции:

SELECT CustomerID, Number_Of_Orders
FROM (SELECT CustomerID, COUNT(*) AS Number_Of_Orders,
             ROW_NUMBER() OVER (ORDER BY COUNT(*) ASC) as seqnum_asc,
             ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC) as seqnum_desc
      FROM Orders
      GROUP BY CustomerID
     ) c
WHERE seqnum_asc = 1 OR seqnum_desc = 1;
1 голос
/ 01 мая 2019

Вы можете использовать оконные функции для этого. Это даст вам несколько клиентов за мин / макс, если есть связи ( fiddle ):

SELECT CustomerID
     , OrderCount
     , CASE WHEN OrderCount = MinOrderCount THEN 'Customer with min orders'
            WHEN OrderCount = MaxOrderCount THEN 'Customer with max orders' END AS Type
FROM (
    SELECT CustomerID
         , COUNT(*) AS OrderCount
         , MIN(COUNT(*)) OVER () AS MinOrderCount
         , MAX(COUNT(*)) OVER () AS MaxOrderCount
    FROM Orders
    GROUP BY CustomerID
) AS x
WHERE OrderCount = MinOrderCount OR OrderCount = MaxOrderCount
1 голос
/ 01 мая 2019

Вы не можете использовать ORDER BY внутри запросов, которые хотите объединить с UNION, но вы можете сделать это:

SELECT * FROM
  (SELECT TOP 1 CustomerID, COUNT(*) AS Number_Of_Orders
  FROM Orders
  GROUP BY CustomerID
  ORDER BY COUNT(*) ASC) t
UNION ALL
SELECT * FROM
  (SELECT TOP 1 CustomerID, COUNT(*) AS Number_Of_Orders
  FROM Orders
  GROUP BY CustomerID
  ORDER BY COUNT(*) DESC) t

Это помогает, хотя и неэффективно, потому что вы выполняете дважды тот же код и сортировка дважды .

...