«Секционированная» сортировка в SQL-запросе - PullRequest
1 голос
/ 09 февраля 2011

Следующий запрос SQL, который отображает проданные товары, отсортированные по стоимости и количеству заказов, должен быть отсортирован по разделам. А именно, продукты со стоимостью менее 100 долларов должны идти в первую очередь, а затем все остальные, которые стоят> 100 долларов, должны следовать за ним. Добавление HAVING TS.TotalSold < 100 к запросу позволит выполнить это для первого раздела, но отфильтрует другие продукты. Операция должна быть атомарной, чтобы этот запрос мог быть выполнен только один раз.

ПРИМЕЧАНИЕ: стоимость, на которую должен быть разделен запрос, рассчитывается как максимум из двух столбцов стоимости, что несколько усложняет ситуацию (предлагаемые решения CASE WHEN не будут работать, так как HighestCost не является столбцом)


SELECT PS.ProductName, TS.TotalSold, 
  ((PS.Cost1 + PS.Cost2 + ABS(PS.Cost1-PS.Cost2)) / 2) as HighestCost
FROM Products as PS
   CROSS APPLY 
      (SELECT 
         (SELECT COUNT(OrderId) 
          FROM Orders as OS 
          WHERE OS.ProductId=PS.ProductId) 
       as TotalSold) TS
ORDER BY HighestCost ASC, TS.TotalSold

РЕДАКТИРОВАТЬ : изменил запрос, включив в него вычисленную стоимость, на которую должен быть разбит запрос.

Ответы [ 2 ]

1 голос
/ 09 февраля 2011

Я не знаю, какие базы данных вы используете, но в моем я бы использовал вычисляемый столбец, чтобы назначить partitionId, и отсортировать по нему.Как то так:

SELECT PS.ProductName, TS.TotalSold,
(if cost < 100 then 1 else 2 endif) as partition
FROM Products as PS
   CROSS APPLY 
      (SELECT 
         (SELECT COUNT(OrderId) 
          FROM Orders as OS 
          WHERE OS.ProductId=PS.ProductId) 
       as TotalSold) TS
ORDER BY partition, PS.Cost ASC, TS.TotalSold
1 голос
/ 09 февраля 2011

EDITED

SELECT *
FROM
(
SELECT PS.ProductName, TS.TotalSold, 
  ((PS.Cost1 + PS.Cost2 + ABS(PS.Cost1-PS.Cost2)) / 2) as HighestCost
FROM Products as PS
   CROSS APPLY 
      (SELECT COUNT(OrderId) as TotalSold
       FROM Orders as OS 
       WHERE OS.ProductId=PS.ProductId) TS
) SQ
ORDER BY CASE WHEN HighestCost > 100 THEN 1 END ASC, TotalSold

оригинал ниже

SELECT PS.ProductName, TS.TotalSold
FROM Products as PS
   CROSS APPLY 
      (SELECT COUNT(OrderId) as TotalSold
       FROM Orders as OS 
       WHERE OS.ProductId=PS.ProductId) TS
ORDER BY
 CASE WHEN TS.TotalSold > 100 THEN 1 END, PS.Cost ASC, TS.TotalSold

Вы можете заметить, что я удалил уровень подзапроса, поскольку он был посторонним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...