Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Найти постоянных клиентов по таблице их заказов  [new]
Alexs_001
Member

Откуда:
Сообщений: 38
Есть 2 классические таблицы:
CUSTOMER( 
    ID int IDENTITY(1,1) NOT NULL,
    [Name] nvarchar(max) NOT NULL
)

[ORDER](
    ID int IDENTITY(1,1) NOT NULL,
    CUSTOMER_ID int NOT NULL,
    [Date] date NOT NULL
)

Нужно найти "постоянных клиентов".

Понятно, что критерий постоянства клиента расплывчатый, поэтому задача свелась к поиску одного самого постоянного клиента, т.е. к такому запросу:

SELECT TOP 1 CUSTOMER_ID
FROM [ORDER]
....
ORDER BY
....

А вот что дальше писать вместо '....' никак не соображу.

Если группировать по CUSTOMER_ID и выбирать CUSTOMER_ID по максимальному к-ву его записей, это не будет "самый постоянный" клиент, так как, например, клиент сделавший 10 заказов в один и тот же день менее постоянный, чем клиент сделавший по 1 заказу в 2 разных дня. Подскажите, какой придумать алгоритм. Ясно, что надо также как-то использовать поле [Date].
14 дек 12, 02:52    [13629638]     Ответить | Цитировать Сообщить модератору
 Re: Найти постоянных клиентов по таблице их заказов  [new]
qwerty112
Guest
Alexs_001,

"постоянный" это, имхо, "смесь" 2-х "ингридиентов" :)) :
- "знаем долго" - max(date_order)-min(date_order)
- "видим часто" - count(distinct date_order)

а вот дальше уже - субьективно, ... - нужно по этим 2-м параметром "взвесить"
например - определить место контрика в рейтинге по первому и по второму параметра отдельно, и вывести с наименьшим суммарным рейтингом
14 дек 12, 03:10    [13629648]     Ответить | Цитировать Сообщить модератору
 Re: Найти постоянных клиентов по таблице их заказов  [new]
Alexs_001
Member

Откуда:
Сообщений: 38
qwerty112,
Сущая правда! Спасибо!
Только вот мож существуют стандартные алгоритмы расчета? CRMщики должны знать.
А то одна система выдаст одних постоянных клиентов, а другая - других, по тем же данным. И какая из них лучше? Это не есть гуд. Сейчас интерфейсы упрощаются, юзеры стают тупее и вряд-ли будут вводить какие нибудь параметры настройки расчета. Хочу жестко забить алгоритм в код.
14 дек 12, 03:55    [13629657]     Ответить | Цитировать Сообщить модератору
 Re: Найти постоянных клиентов по таблице их заказов  [new]
aleks2
Guest
qwerty112
Alexs_001,

"постоянный" это, имхо, "смесь" 2-х "ингридиентов" :)) :
- "знаем долго" - max(date_order)-min(date_order)
- "видим часто" - count(distinct date_order)

а вот дальше уже - субьективно, ... - нужно по этим 2-м параметром "взвесить"
например - определить место контрика в рейтинге по первому и по второму параметра отдельно, и вывести с наименьшим суммарным рейтингом


ишо есть "платит многа" = sum(уплаченные деньги).

ЗЫ. оно ведь, если клиент многа платит - то черт с ним, что появляется не так уж часто...
14 дек 12, 07:46    [13629744]     Ответить | Цитировать Сообщить модератору
 Re: Найти постоянных клиентов по таблице их заказов  [new]
Alexs_001
Member

Откуда:
Сообщений: 38
aleks2,
поля уплаченные деньги нету в условии слава Богу, но мысль правильная.

Пришла в голову одна простая идея: Кто-нибудь может подтвердить или опровергнуть утверждение:
"Чем больше дисперсия даты заказа клиента, тем постояннее клиент"?
CRMщики должны знать лучше.
Если это так, тогда вот:
/*возвращает @N постоянных клиентов за период с @StartDate по @EndDate*/
ALTER PROCEDURE [dbo].[usp_RegularClientListN]
	@N int = 10, 
	@StartDate date = NULL, 
	@EndDate date = NULL
AS
BEGIN
SET NOCOUNT ON;

IF @StartDate IS NULL SET @StartDate = (SELECT MIN([Date]) FROM [ORDER])
IF @EndDate IS NULL SET @EndDate = (SELECT MAX([Date]) FROM [ORDER])

IF OBJECT_ID('tempdb..#t') IS NOT NULL DROP TABLE #t

SELECT
	[Name],
	regularity
INTO #t
FROM
	(
	SELECT
		CLIENT_ID,
		
		-- VARP (DISTINCT, some_value) - дисперсия заполнения всех значений в some_value. 
		-- Предполагаем, что чем больше дисперсия даты заказа клиента, тем постояннее клиент.
		VARP( DISTINCT 
			-- преобразование типа данных date в int не разрешено, поэтому сначала преобразовываем date в datetime
			CAST(CAST([DATE] AS datetime) AS int) 
		) AS regularity
		
	FROM 
		[ORDER]
	WHERE
		[DATE] Between @StartDate AND @EndDate 
	GROUP BY
		CLIENT_ID
	ORDER BY
		regularity DESC
	) AS RegularClient
	
	JOIN CLIENT ON CLIENT.ID = RegularClient.CLIENT_ID

EXEC ('
SELECT TOP ' + @N + ' * FROM #t
')

DROP TABLE #t
END
14 дек 12, 08:56    [13629874]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить