Упорядочить по мере, но сохранить связанные строки вместе - PullRequest
1 голос
/ 10 июля 2019

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

Поскольку мои данные немного сложны, я взял пример данных.

Здесьэто извлечение таблицы данных (необработанные данные):

Products --- Qty --- Info
Chair --- 1 --- Sold
Lamp --- 1 --- Sold
Chair --- 3 --- Sold
Chair --- 1 --- Sold
Chair --- 2 --- Sold
Table --- 4 --- Sold
Computer --- 2 --- Sold
Chair --- 1 --- Returned
Table --- 1 --- Sold
Desk --- 3 --- Sold
Chair --- 2 --- Returned
Etc. (a lot of lines)

Вот результат, когда я делаю сумму (только количество QTY, в зависимости от того, продано ли оно или возвращено в двух разныхстолбцы) - ORDER BY: QtySold, затем QtyRet, затем Prod

Prod --- QtySold --- QtyRet --- Info
Chairs --- 95 ------ / ------ Sold
Tables  --- 33 ------ / ------ Sold
Book --- 22 ------ / ------ Sold
Computer --- 22 ------ / ------ Sold
Lamp --- 19 ------ / ------ Sold
Desk --- 11 ------ / ------ Sold
Chairs --- / ------ 5 ------ Returned
Computer --- / ------ 2 ------ Returned
Tables --- / ------ 2 ------ Returned

Я хочу заказать их по-другому: в этом примере я хочу заказать по QtySold, однако еслиProd появляется дважды, я хочу, чтобы второй находился непосредственно под первым (например, стулья - 95 - / - продано, затем стулья - / - 5 - возвращено и т. Д.)

Вот код (этоМожет содержать ошибку, как я написал здесь):

SELECT
Prod=ttt.Prod,
QtySold=ttt.QtySold=CONVERT(Decimal(5,1),SUM(ISNULL(ttt.QtySold,0))),
QtyRet=CONVERT(Decimal(5,1),SUM(ISNULL(ttt.QtyRet,0))),
Info=ttt.Info

FROM(

SELECT    
Prod=nte.Products,
QtySold=(CASE WHEN (ISNULL(nte.Info,'0')='Sold') THEN ISNULL(nte.Qty,0) ELSE 0 END),
QtyRet=(CASE WHEN (ISNULL(nte.Info,'0')='Sold') THEN 0 ELSE ISNULL(nte.Qty,0) END),
Info=nte.Info

FROM
nametableexemple nte

)ttt
GROUP BY ttt.Prod, ttt.Info
ORDER BY ttt.QtySold DESC, ttt.QtyRet DESC, ttt.Prod -- Here is the issue

Результат, который я хотел бы получить:

Prod --- QtySold --- QtyRet --- Info
Chairs --- 95 ------ / ------ Sold
Chairs --- / ------ 5 ------ Returned --(because Chair is first with 95 Sold)
Tables  --- 33 ------ / ------ Sold
Tables --- / ------ 2 ------ Returned --(because Table is 2nd with 33 Sold)
Book --- 22 ------ / ------ Sold
Computer --- 22 ------ / ------ Sold
Computer --- / ------ 2 ------ Returned --(because Computer is 4th w 22Sold)
Lamp --- 19 ------ / ------ Sold
Desk --- 11 ------ / ------ Sold

(Упорядочение QtySold по DESC: 95 - 33- 22 - 22 - 19 - 11) (Но первый элемент (стулья) также является «возвращенной» информацией, поэтому мне нужно, чтобы она отображалась непосредственно под ней)

Можно ли сделать «заказ по» по-другому?Я хотел бы избежать создания UNION ALL, так как мои таблицы содержат слишком много столбцов.

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Попробуйте с CTE, как показано ниже -

WITH CTE
AS
(
    SELECT Products,SUM(qty) Q,Info
    FROM your_table
    GROUP BY Products,Info
)

SELECT A.*
FROM CTE2 A
ORDER BY 
(SELECT Q FROM CTE2 B WHERE B.Info = 'Sold' AND B.Products = A.Products)  DESC,
1, 
CASE WHEN info = 'Sold' THEN 1 ELSE 2 END
0 голосов
/ 10 июля 2019

Создайте CTE и включите в него ваш запрос (без предложения ORDER BY), а затем выполните условную сортировку:

with cte as (
  <your query here>
)
select * from cte c
order by 
  case 
    when coalesce(c.QtySold, 0) <> 0 then c.QtySold
    else (select QtySold from cte where prod = c.prod and coalesce(QtySold, 0) <> 0) 
  end desc,
  QtySold DESC, prod

Функция coalesce() необходима, только если QtySold равно nullв строках 'Returned'.Если это 0, используйте это:

order by 
  case 
    when c.QtySold <> 0 then c.QtySold
    else (select QtySold from cte where prod = c.prod and QtySold <> 0) 
  end desc,
  QtySold DESC, prod
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...