#sql #soql
Вопрос:
На данный момент мой запрос выглядит так:
SELECT TOP 1000
Yr, Mnth, Product, SUM(Price * Amount)
FROM
(SELECT
Random_product_name AS Product, Random_price AS Price,
Random_quantity AS Amount,
Random_order_dt AS Order_date,
YEAR(Random_order_dt) AS Yr, MONTH(Random_order_dt) AS Mnth
FROM
Random_table_1 a
JOIN
Random_table_2 b ON a.Random_ID = b.Random_ID
WHERE
a.Random_product_name LIKE 'XX_%'
AND a.Random_country = 'XX'
AND a.Random_price != 0
AND b.Random_order_dt BETWEEN 'Jan 01 2019 12:00AM' AND 'Jul 01 2021 12:00AM') x
GROUP BY
Yr, Mnth, Product
ORDER BY
Yr, CONVERT(INT, Mnth), CONVERT(INT, SUM(Price*Amount)) DESC
Не обращайте внимания на детали, реальный запрос, конечно, выглядит немного иначе. Но результат этого может выглядеть так:
Год | Mnth | Продукт | СУММА |
---|---|---|---|
2019 | 1 | A | 100 000 |
2019 | 1 | B | 90 000 |
2019 | 1 | C | 80 000 |
2019 | 1 | D | 70 000 |
2019 | 1 | E | 60 000 |
2019 | 1 | F | 50 000 |
2019 | 1 | G | 40 000 |
2019 | 2 | B | 120 000 |
2019 | 2 | A | 110 000 |
2019 | 2 | D | 90 000 |
2019 | 2 | C | 80 000 |
2019 | 2 | E | 60 000 |
2019 | 2 | G | 30 000 |
2019 | 2 | F | 20 000 |
И так далее вплоть до июля 2021 года. Сумма продуктов меняется каждый месяц, и чего я хотел бы добиться, так это отображать только верхние 3 из них за каждый месяц, но в одной таблице, вот так:
Год | Mnth | Продукт | СУММА |
---|---|---|---|
2019 | 1 | A | 100 000 |
2019 | 1 | B | 90 000 |
2019 | 1 | C | 80 000 |
2019 | 2 | B | 120 000 |
2019 | 2 | A | 110 000 |
2019 | 2 | D | 90 000 |
И так далее. Опять же, вплоть до июля 2021 года.
Запрос упрощен. На самом деле это выглядит немного сложнее, но я надеюсь, что достаточно понятно, чего я хочу достичь. Я не знаю, как поступить, поэтому я был бы признателен за любую помощь, которую вы можете предоставить! Заранее благодарю вас!
Ответ №1:
Вы можете использовать row_number с предложением partition_by в своем операторе select, а затем использовать результат в своем предложении where.
Чтобы добавить в начало -выберите :
row_number() over(partition by Yr, Mnth order by SUM(Price * Amount) desc) as rownum
Затем добавьте select поверх следующего предложения where:
WHERE rownum <= 3
Ответ №2:
Я думаю, что ROW_NUMBER может вам помочь
Я не мог протестировать, и я знаю, что это не очень хорошее решение, но я думаю, что это общая идея:
SELECT * FROM
(SELECT
Yr, Mnth, Product, sold
ROW_NUMBER() OVER (
PARTITION BY Yr, Mnth, Product
ORDER BY sold DESC
) item_rank
FROM
(
SELECT TOP 1000
Yr, Mnth, Product, SUM(Price * Amount) as sold
FROM
(SELECT
Random_product_name AS Product, Random_price AS Price,
Random_quantity AS Amount,
Random_order_dt AS Order_date,
YEAR(Random_order_dt) AS Yr, MONTH(Random_order_dt) AS Mnth
FROM
Random_table_1 a
JOIN
Random_table_2 b ON a.Random_ID = b.Random_ID
WHERE
a.Random_product_name LIKE 'XX_%'
AND a.Random_country = 'XX'
AND a.Random_price != 0
AND b.Random_order_dt BETWEEN 'Jan 01 2019 12:00AM' AND 'Jul 01 2021 12:00AM') x
GROUP BY
Yr, Mnth, Product
ORDER BY
Yr, CONVERT(INT, Mnth), CONVERT(INT, SUM(Price*Amount)) DESC
)
)
WHERE item_rank <= 3