поэтому у меня есть запрос, в котором указывается каждый мой город, соответствующий штат и стоимость, которую мои клиенты потратили в этом городе.
Я бы хотел определить топ-3 по TotalCustomerValue для каждого города.
Запрос немного сложнее, но суть его:
SELECT DISTINCT
--*
LTRIM(RTRIM(cs.City)) City
,LTRIM(RTRIM(cs.State)) State
,SUM(cs.TotalCustomerValueOverBase) over (partition by cs.City, cs.State) TotalCustomerValue
,SUM(cs.TotalOrdersBase) over (partition by cs.City, cs.State) TotalOrders
FROM ( -- This table gives full customer information per customer.
)CSS
То, что я хочу сделать, - это создать таблицу, в которой будут находиться 3 верхние города каждого штата, а затем другая строка (которая будет обрабатываться как любая другая строка), которая будет суммой всех других городов. Таким образом, общая таблица будет иметь 200 строк (50 * 4).
Я пытаюсь что-то сделать с номером строки, но я не могу сработать
,ROW_NUMBER() over (partition by cs.City, cs.State Order by sum(CS.TotalCustomerValueOverBase)) rowNr
Тогда я мог бы попытаться сложить все числа больше 3.
У кого-нибудь есть идеи?
А затем я предполагаю, что SSRS, когда я хочу создать визуалы с этими данными, я могу просто создать как фильтр для всех строк с ключевым словом Other, верно?
Вот мой полный запрос (с попыткой реализовать решение Гордона)
SELECT
(case when CSS.seqnum <= 3 then city else 'Others' end) as city,
(case when seqnum <= 3 then state end) as state
sum(TotalCustomerValue) as TotalCustomerValue,
sum(TotalOrders) as TotalOrders
FROM
(
SELECT DISTINCT
--*
LTRIM(RTRIM(cs.City)) City
,LTRIM(RTRIM(cs.State)) State
,right(left(lat, len(lat) -1),len(lat) -2) lat -- the lat and long are wrapped in quotes
,right(left(lng, len(lng) -1),len(lng) -2) lng -- so i have to do the left right to get rid of them.
,SUM(cs.TotalCustomerValueOverBase) over (partition by cs.City, cs.State) TotalCustomerValue
,SUM(cs.TotalOrdersBase) over (partition by cs.City, cs.State) TotalOrders
--,SUM(cs.TotalQuantityOverBase) over (partition by cs.City, cs.State) TotalQuantity
,CONVERT(float, right(left(population_proper, len(population_proper) -1),len(population_proper) -2)) population_proper
,CAST(
SUM(cs.TotalOrdersBase) over (partition by cs.City, cs.State)
/
NULLIF(convert(float, right(left(population_proper, len(population_proper) -1),len(population_proper) -2)),0)--*100
as decimal(10,4)) AS OrderDensityPercent
,SUM(cs.BrandNewCustomer) over (partition by cs.City, cs.State) BrandNewCustomers
,SUM(cs.RecurringCustomer) over (partition by cs.City, cs.State) RecurringCustomers
,SUM(cs.ReactivatedCustomer) over (partition by cs.City, cs.State) ReactivatedCustomers
,row_number() over (partition by ltrim(rtrim(cs.State)) order by sum(cs.TotalCustomerValueOverBase) desc) as seqnum
FROM ( -- This table gives full customer information per customer.
SELECT
CC.CustomerEmail
,CC.Month Month
,CONCAT(CC.Year, '-', CASE WHEN CC.Month < 10 then '0' else '' end, CC.Month) Date
,CASE WHEN
( ISNULL(CC.TotalOrdersCustomerBase,0) >= 1
AND ISNULL(RC.TotalOrdersRecurringBase,0) = 0
AND ISNULL(LC.TotalOrdersLifetimeBase,0) = 0)
THEN 1 ELSE 0 END BrandNewCustomer
,CASE WHEN
( ISNULL(CC.TotalOrdersCustomerBase,0) >= 1
AND ISNULL(RC.TotalOrdersRecurringBase,0) >= 1)
THEN 1 ELSE 0 END RecurringCustomer
,CASE WHEN
( ISNULL(CC.TotalOrdersCustomerBase,0) >= 1
AND ISNULL(RC.TotalOrdersRecurringBase,0) = 0
AND ISNULL(LC.TotalOrdersLifetimeBase,0) >= 1)
THEN 1 ELSE 0 END ReactivatedCustomer
,ISNULL(CC.TotalCustomerValueOverCustomerBase,0) TotalCustomerValueOverCustomerBase
,ISNULL(CC.TotalOrdersCustomerBase,0) TotalOrdersCustomerBase
,ISNULL(CC.TotalQuantityOverCustomerBase,0) TotalQuantityOverCustomerBase
,ISNULL(RC.TotalCustomerValueOverRecurringBase,0) TotalCustomerValueOverRecurringBase
,ISNULL(RC.TotalOrdersRecurringBase,0) TotalOrdersRecurringBase
,ISNULL(RC.TotalQuantityOverRecurringBase,0) TotalQuantityOverRecurringBase
,ISNULL(LC.TotalCustomerValueOverLifetimeBase,0) TotalCustomerValueOverLifetimeBase
,ISNULL(LC.TotalOrdersLifetimeBase,0) TotalOrdersLifetimeBase
,ISNULL(LC.TotalQuantityOverLifetimeBase,0) TotalQuantityOverLifetimeBase
,ISNULL(FC.TotalCustomerValueOverBase,0) TotalCustomerValueOverBase
,ISNULL(FC.TotalOrdersBase,0) TotalOrdersBase
,ISNULL(FC.TotalQuantityOverBase,0) TotalQuantityOverBase
,ISNULL(CC.TotalCustomersOverCustomerBase,0) TotalCustomersOverCustomerBase
,ISNULL(RC.TotalCustomersOverRecurringBase,0) TotalCustomersOverRecurringBase
,ISNULL(LC.TotalCustomersOverLifetimeBase,0) TotalCustomersOverLifetimeBase
,ISNULL(FC.TotalCustomersOverBase,0) TotalCustomersOverBase
,CC.City
,CC.State
,CC.CountryCode
From
(
SELECT
C.CustomerEmail
,C.Month
,C.Year
,C.TotalCustomersOverCustomerBase
,C.TotalCustomerValueOverCustomerBase
,C.TotalOrdersCustomerBase
,C.TotalQuantityOverCustomerBase
,C.City
,C.State
,C.CountryCode
FROM
#CustomerBase C
WHERE C.OrderCountCustomerBase = 1 -- This makes it return only the first row of a customer with multiple purchases.
--and TotalOrdersCustomerBase = TotalQuantityOverCustomerBase
) CC
LEFT JOIN
(
SELECT
R.CustomerEmail
,R.TotalCustomersOverRecurringBase
,R.TotalCustomerValueOverRecurringBase
,R.TotalOrdersRecurringBase
,R.TotalQuantityOverRecurringBase
FROM
#RecurringBase R
WHERE R.OrderCountRecurringBase = 1
) RC ON CC.CustomerEmail = RC.CustomerEmail
LEFT JOIN
(
SELECT
L.CustomerEmail
,L.TotalCustomersOverLifetimeBase
,L.TotalCustomerValueOverLifetimeBase
,L.TotalOrdersLifetimeBase
,L.TotalQuantityOverLifetimeBase
FROM
#LifetimeBase L
WHERE L.OrderCountLifetimeBase = 1
) LC ON CC.CustomerEmail = LC.CustomerEmail
LEFT JOIN
(
SELECT
F.CustomerEmail
,F.TotalCustomersOverBase
,F.TotalCustomerValueOverBase
,F.TotalOrdersBase
,F.TotalQuantityOverBase
FROM
#FullBase F
WHERE F.OrderCountBase = 1
) FC ON CC.CustomerEmail = FC.CustomerEmail
) Cs --Customers
LEFT JOIN [A1Warehouse].[dbo].[uscities] Ci ON cs.City = right(left(ci.city_ascii, len(ci.city_ascii) -1),len(ci.city_ascii) -2) and cs.State = right(left(ci.state_id, len(ci.state_id) -1),len(ci.state_id) -2)
WHERE
LAT IS NOT NULL
AND LNG IS NOT NULL
group by ltrim(rtrim(cs.City)), ltrim(rtrim(cs.State))
)CSS
Where CAST(CSS.LAT AS FLOAT) > 20 AND CAST(CSS.LNG AS FLOAT) > -120
group by (case when seqnum <= 3 then city else 'Others' end),
(case when seqnum <= 3 then state end)
ORDER BY TotalCustomerValue DESC