#sql #sql-server-2008 #window-functions
#sql #sql-server-2008 #окно-функции
Вопрос:
Этот вопрос был рассмотрен аналогично ранее, НО я борюсь.
Мне нужно найти top N продаж на основе шаблонов покупок клиентов..
в идеале это должно быть top N для каждого клиента по месяцам и годам, но сейчас я просто смотрю на top N по всей базе данных.
Мой запрос выглядит так:
-- QUERY TO SHOW TOP 2 CUSTOMER INVOICES BY CUSTOMER BY MONTH
SELECT
bill_to_code,
INVOICE_NUMBER,
SUM( INVOICE_AMOUNT_CORP ) AS 'SALES',
ROW_NUMBER() OVER ( PARTITION BY bill_to_code ORDER BY SUM( INVOICE_AMOUNT_CORP ) DESC ) AS 'Row'
FROM
FACT_OM_INVOICE
JOIN dim_customer_bill_to ON FACT_OM_INVOICE.dim_customer_bill_to_key = dim_customer_bill_to.dim_customer_bill_to_key
--WHERE
-- 'ROW' < 2
GROUP BY
invoice_number,
Dim_customer_bill_to.bill_to_code
Я не могу понять решения, данные для ограничения строки =< N.
Пожалуйста, помогите.
Комментарии:
1. Ваш запрос не выглядит далеким. Номер строки будет нумеровать записи в каждой группе в соответствии с порядком. Затем вы можете ограничить доступ к первым двум записям из каждой группы.
2. Вам не нужно
ROW_NUMBER
, просто сделайтеSELECT TOP 2
с верхним уровнемORDER BY
Ответ №1:
Попробуйте это.
-- QUERY TO SHOW TOP 2 CUSTOMER INVOICES BY CUSTOMER BY MONTH
;WITH Top2Customers
AS
(
SELECT
bill_to_code,
INVOICE_NUMBER,
SUM( INVOICE_AMOUNT_CORP ) AS 'SALES',
ROW_NUMBER() OVER ( PARTITION BY bill_to_code ORDER BY SUM( INVOICE_AMOUNT_CORP ) DESC )
AS 'RowNumber'
FROM
FACT_OM_INVOICE
JOIN dim_customer_bill_to ON FACT_OM_INVOICE.dim_customer_bill_to_key = dim_customer_bill_to.dim_customer_bill_to_key
GROUP BY
invoice_number,
Dim_customer_bill_to.bill_to_code
)
SELECT * FROM Top2Customers WHERE RowNumber < 3
Комментарии:
1. Спасибо, Шива! Это работает. Можете ли вы объяснить часть «с top2customers as». Это объявление временной таблицы?
2. Прохладный. Да,
WITH top2customers AS
это похоже на временную таблицу, но более мощную. Это называется CTE — общим табличным выражением. Смотрите это для получения дополнительной информации и примеров: technet.microsoft.com/en-us/library/ms190766 (v=sql.105).aspx
Ответ №2:
Вы должны обернуть свой выбор в другой, чтобы использовать значение, созданное row_number()
select * from (
SELECT
bill_to_code,
INVOICE_NUMBER,
SUM( INVOICE_AMOUNT_CORP ) AS SALES,
ROW_NUMBER() OVER ( PARTITION BY bill_to_code ORDER BY SUM( INVOICE_AMOUNT_CORP ) DESC ) AS RowNo
FROM
FACT_OM_INVOICE
JOIN dim_customer_bill_to ON FACT_OM_INVOICE.dim_customer_bill_to_key = dim_customer_bill_to.dim_customer_bill_to_key
--WHERE
-- 'ROW' < 2
GROUP BY
invoice_number,
Dim_customer_bill_to.bill_to_code
) base where RowNo < 2
Комментарии:
1. Спасибо, Ян, но этот все еще выдает страшную ошибку «Ошибка преобразования не удалась при преобразовании значения varchar ‘row’ в тип данных int.».
2. Я изменил имена столбцов из вашего примера, попробуйте сейчас.