2015-05-29 15 views
0

Я пытаюсь получить счет, с помощью которого наша клиентская база росла каждый месяц.T-SQL количество уникальных записей по месяцам

Например. «Джош», «Тим» и «Дастин» воспользовались услугой в январе, поэтому в январе количество новых уникальных клиентов будет равно 3.

В феврале «Джош», «Тим» и «Ева» используйте услугу. Как «Джош» и «Tim» использовал услугу ранее, количество новых уникальных клиентов будет 1.

И так далее ....

Я хотел использовать КРОМЕ заявление, но очевидно, что это не получая правильных результатов.

SELECT COUNT(DISTINCT Name) as NewUniqueCustomers, convert(varchar(7), RegDate, 126) 
FROM T 
GROUP BY convert(varchar(7), RegDate, 126) 
EXCEPT 

--This should excludie all customers which was included previously 
SELECT COUNT(DISTINCT Name)as NewUniqueCustomers, convert(varchar(7), RegDate, 126) 
FROM T 
WHERE convert(varchar(7), DATEADD(month,-1,RegDate) , 126) 

GROUP BY convert(varchar(7), RegDate, 126) 

http://sqlfiddle.com/#!3/73621

+0

Просто примечание. Вместо преобразования дат в строки используйте 'cast (RegDate as Date)'. Преобразование не позволяет серверу использовать индексы и приводит к очень плохой производительности. –

+0

Я бы хотел, чтобы они были сгруппированы по ГОДУ-МЕСЯЦЕ. Я просто пытаюсь найти способ исключить имена, которые были включены в предыдущий месяц – Petrik

+0

какой-то код, выполняющий вставку пользователей? если это так, почему бы не вставить проверить, существует ли пользователь и добавить флаг, который он уже существует или нет, подсчет намного проще, вы можете добавить условие, чтобы считать только тех пользователей, с которыми вы были отмечены как новые – Sherlock

ответ

3

Использование sqlfiddle это должно сделать это.

with SortedData as 
(
    select * 
     , ROW_NUMBER() over(partition by Name order by RegDate) as RowNum 
    from t 
) 

select dateadd(month, datediff(month, 0, RegDate), 0) 
    , COUNT(Name) 
from SortedData sd 
where sd.RowNum = 1 
group by dateadd(month, datediff(month, 0, RegDate), 0) 

--EDIT--

Учитывая свой комментарий о необходимости тянуть из двух таблиц с профсоюзом, почему не что-то вроде этого?

with SortedData as 
(
    select * 
     , ROW_NUMBER() over(partition by Name order by RegDate) as RowNum 
    from 
    (
     SELECT * FROM ProductionTable 
     UNION ALL 
     SELECT * FROM Archive.dbo.T 
    ) 
    x 
) 
+0

Это работает отлично, однако в живой системе мне нужно СОЕДИНИТЬ ВСЕ две таблицы (Live и архивную базу данных). Обычно я выполняю подзапрос, такой как FROM (SELECT * FROM T UNION ALL SELECT * FROM Archive.dbo.T), но я получаю ошибку в этом подзапросе. Есть идеи? – Petrik

+0

Спасибо. Я полностью забыл, что после подзапроса мне нужна таблица псевдонимов. – Petrik

Смежные вопросы