TSQL Row_Number

#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. Я изменил имена столбцов из вашего примера, попробуйте сейчас.