Как написать хранимую процедуру для возврата количества событий, сгруппированных по недельным блокам «X»? - PullRequest
0 голосов
/ 18 июля 2010

У меня есть таблица, которая фиксирует рыночные взаимодействия сотрудников с клиентами. Соответствующие поля должны быть :чути, дата и тип клиента.

Я хочу, чтобы можно было рассчитывать количество взаимодействий по 5-недельным блокам, начиная с промежуточных дат, которые будут представлены пользователем и различаются по типу клиента a, b, c.

Я хочу иметь возможность взять возвращенные данные и создать серии a, b и c с количеством взаимодействий на рынке, сгруппированных по 5-недельным блокам.

Что-то вроде:

 double[] byValues = { 14, 16, 18, 19, 15, 18, 19, 14, 15 };

 string[] bxValues = { "50", "45", "40", "35", "30", "25", "20", "15", "10" };

, который может быть A-Series. Как только у меня появятся серии A, B и C, я смогу добавить их в график с накоплением.

Я бы также хотел, чтобы пользователь мог настраивать X = 5 от 1 до 20, поэтому было бы неплохо иметь эту переменную как динамическую. Любые указатели или URL будут оценены.

Сначала я хотел сделать один запрос и создать временную таблицу с дополнительным полем, которое заполняется оператором if с некоторой математикой, которая вычисляет ранг блока записи в соответствии с ее датой. Тогда я мог бы запросить это с количеством групп по другим критериям. Но я действительно не уверен, каков самый эффективный способ сделать этот первый шаг. Похоже, что я могу ошибиться, возможно, на порядки.

UPDATE:

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

SELECT  mi1.[CAQ] AS CAQ, FLOOR(DATEDIFF(d, mi1.IDate, CONVERT(datetime, '11/07/2010', 103))/5) AS X_AXISBLOCK 
INTO #myTempTable
FROM [ql10_crm].[MarketInteraction] mi1 INNER JOIN [ql10_crm].[TerritoryCustomer] 
ON mi1.[CustomerId] =[ql10_crm].[TerritoryCustomer].[CustomerId] 
WHERE mi1.[CAQ] IN(1,2,4) AND 
[ql10_crm].[TerritoryCustomer].[TerritoryId] IN(19) AND (mi1.[IDate] BETWEEN CONVERT(datetime, '18/06/2009', 103) AND  CONVERT(datetime, '11/07/2010', 103));

SELECT CAQ, X_AXISBLOCK , COUNT([CAQ])
FROM #myTempTable
GROUP BY CAQ, X_AXISBLOCK 
ORDER BY CAQ, X_AXISBLOCK;

Не уверен, насколько он эффективен или гибок в сравнении с ответами. Придется проверить.

Это мой вывод (CAQ, X_AXISBLOCK, COUNT), где CAQ 1 = A, 2 = B, 4 = C:

2 0 2
2 1 6
2 6 2
4 0 3
4 1 5
4 6 4

Ответы [ 2 ]

0 голосов
/ 18 июля 2010

Просто мысль, но мне кажется, что вы могли бы сделать это на чистом SQL (обычно предпочтительнее), вместо того чтобы прибегать к хранимой процедуре.

Посмотрите на доступные вам аналитические функции здесь . Они уже давно хорошо поддерживаются в Oracle, но теперь находят применение в SQL Server.

Например, вы бы смотрели на что-то вроде этого (ни в коем случае не полное решение - просто указатель):

SELECT a.custid,
       a.weekblock,
       COUNT(a.custid) OVER (PARTITION BY a.weekblock, a.custid)
  FROM (SELECT x.custid, DATEPART(wk, x.date) / 5 AS weekblock
          FROM market x) a

Если вы предоставите больше информации о структуре таблицы, возможно, будет найдено лучшее решение.

0 голосов
/ 18 июля 2010

Вы немного потеряли меня из-за разговоров о временных таблицах и рангах блоков, но разве это не сделает то, что вам нужно?

DECLARE @X INT
SET @X =5

DECLARE @endDate DATETIME
DECLARE @startDate DATETIME

SET @endDate = '2010-07-18'
SET @startDate = '2009-07-18'

DECLARE @EndDateDays INT
SET @EndDateDays = CAST(@endDate AS INT);



WITH MarketInteractions AS
(
SELECT 1 AS customerid, CAST('2010-07-18' AS DATETIME) AS [DATE], 'a' AS CustomerType
UNION ALL
SELECT 1 AS customerid, CAST('2010-06-18' AS DATETIME) AS [DATE], 'b' AS CustomerType
UNION ALL
SELECT 1 AS customerid, CAST('2010-05-18' AS DATETIME) AS [DATE], 'a' AS CustomerType

),
MarketInteractions2 AS 
(
SELECT 1+ ((CAST(@endDate - [DATE] AS INT)) / (@X * 7)) AS Period, customerid, CustomerType
FROM MarketInteractions
WHERE [DATE] BETWEEN @startDate AND @endDate AND CustomerType IN ('a','b','c')
)

/* Possibly with a join on a numbers table to get periods with zero interactions if 
 that is possible*/

SELECT 
Period, 
COUNT(CASE WHEN CustomerType = 'a' THEN 1 END) AS a,
COUNT(CASE WHEN CustomerType = 'b' THEN 1 END) AS b,
COUNT(CASE WHEN CustomerType = 'c' THEN 1 END) AS c
FROM MarketInteractions2
GROUP BY Period,  CustomerType 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...