Как использовать Pivot в SQL Server? - PullRequest
0 голосов
/ 30 октября 2018

У меня есть две таблицы со столбцами, как указано ниже:

ЗАКАЗЧИК таблица как DIM_CUSTOMER :

ID_CUSTOMER, CUSTOMER_NAME

СДЕЛКА таблица как FACT_TRANSACTION :

ID_CUSTOMER, DATE, TOTAL_PRICE, QUANTITY

Постановка проблемы

Найти 100 лучших клиентов и их средние расходы, среднее количество по каждому году. Также найдите процент изменения в их расходах.

Мой подход:

SELECT TOP 100 
    YEAR(FT.DATE) AS [YEAR],
    FT.ID_CUSTOMER AS [CUSTOMER NAME],
    FT.TOTAL_PRICE AS [TOTAL AMT],
    AVG(FT.TOTAL_PRICE) AS [AVG SPEND],
    AVG(FT.QUANTITY) AS [AVG QUANTITY]
FROM 
    FACT_TRANSACTIONS FT
INNER JOIN 
    DIM_CUSTOMER DC ON FT.ID_CUSTOMER = DC.ID_CUSTOMER
GROUP BY 
    FT.DATE, FT.ID_CUSTOMER, FT.TOTAL_PRICE
ORDER BY 
    3 DESC 

Это приводит к 100 лучших клиентов в зависимости от их использования.

Теперь мне нужно определить процентное изменение их расходов в ГОДУ.

Как я могу это сделать? Вероятно, использование опции PIVOT здесь поможет, но я не уверен.

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Не могли бы вы попробовать следующий запрос SQL CTE?

;with topcustomers as(
    SELECT distinct top 100
        ID_CUSTOMER,
        SUM(TOTAL_PRICE) over (partition by ID_CUSTOMER) as TotalSPEND
    FROM FACT_TRANSACTION
    order by TotalSPEND desc
), cte as (
    SELECT
        distinct
        t.ID_CUSTOMER, YEAR(t.DATE) [YEAR], TotalSPEND,
        AVG(t.QUANTITY * 1.0) over (partition by t.ID_CUSTOMER, YEAR(t.DATE)) as AverageQUANTITY,
        AVG(t.TOTAL_PRICE * 1.0) over (partition by t.ID_CUSTOMER, YEAR(t.DATE)) as AverageSPEND
    FROM FACT_TRANSACTION t
    INNER JOIN topcustomers c on c.ID_CUSTOMER = t.ID_CUSTOMER
)
select 
    *,
    ( AverageSPEND - lag(AverageSPEND,1) over (partition by ID_CUSTOMER order by [YEAR]) ) * 100.0 / AverageSPEND as [%Change]
from cte
0 голосов
/ 30 октября 2018

Вы можете попробовать использовать LAG , чтобы получить доступ к предыдущему [AVG SPEND] для текущей строки. Идея состоит в том, чтобы сгруппировать данные для каждого [CUSTOMER NAME], используя PARTITION BY, а затем упорядочить данные по [YEAR]. Функция даст нам предыдущий результат, и мы можем легко рассчитать разницу.

Попробуйте что-то вроде этого:

SELECT TOP 100 
    YEAR(FT.DATE) AS [YEAR],
    FT.ID_CUSTOMER AS [CUSTOMER NAME],
    FT.TOTAL_PRICE AS [TOTAL AMT],
    AVG(FT.TOTAL_PRICE) AS [AVG SPEND],
    AVG(FT.QUANTITY) AS [AVG QUANTITY]
INTO #DataSource
FROM 
    FACT_TRANSACTIONS FT
INNER JOIN 
    DIM_CUSTOMER DC ON FT.ID_CUSTOMER = DC.ID_CUSTOMER
GROUP BY 
    YEAR(FT.DATE), FT.ID_CUSTOMER, FT.TOTAL_PRICE
ORDER BY 
    [AVG SPEND] DESC 

SELECT *
      ,[AVG SPEND] - LAG([AVG SPEND], 1, 0) OVER (PARTITION BY [CUSTOMER NAME] ORDER BY [YEAR])
FROM #DataSource

Обратите внимание, что:

  • функция требует SQL Server 2012 +
  • вы можете изменить разделение и порядок, как вам нравится, чтобы удовлетворить вашу реальную цель (например, вы можете использовать ORDER BY [YEAR] DESC
  • Вы можете использовать функцию LEAD, чтобы получить доступ к следующему значению в группе, если вы хотите рассчитать разницу в Advace
  • Я материализовал данные во временной таблице, но вы можете использовать переменную таблицы или все, что вы используете
...