Выберите пользователей на основе их даты присоединения и оставленной даты - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть следующая таблица:

Персона

UserID Name Date_Joined Date_Left 
1      Test  2018-08-10 NULL
2      Test2 2018-07-10 NULL
3      Test3 2018-07-10 2018-12-31
4      Test4 2018-08-10 2018-09-10

Я хочу проверить только по дате их присоединения и / или оставлению, если они подлежат оплате (=активный) или нет.

Это платные пользователи:

  1. Пользователь, чей начальный месяц составляет не менее одного месяца до даты биллдата, дата не указана

  2. Пользователь, чей начальный месяц составляет не менее одного месяца до даты билдата, с датой оставшегося месяца, равной дате билда или позже, чем дата билда

Месяц выставления счета = всегда в предыдущем месяце.

Я использую следующий запрос:

DECLARE @billdate AS DATE = '2018-09-01';
SELECT * 
FROM person
WHERE CompanyID = 1205 AND (
    (
        date_joined <= EOMONTH(@billdate, -1)
    )
    OR
    (
        date_left >  EOMONTH(@billdate, -1) AND
        date_left <= EOMONTH(@billdate)
    )
)

Мои проблемы:

  • User Test4 все еще присутствует в моей таблице, если я установил billdate на 2018-11-01.
  • Тест пользователя 3 пропадает, если я установил billdate на 2019-01-01

Что не так с моим запросом и как я могу его оптимизировать?

Пример данных:

Список пользователей:

1 - Тест - 2018-08-10 - NULL

2 - Тест2- 2018-07-10 - NULL

3 - Test3 - 2018-07-10 - 2018-12-31

4 - Test4 - 2018-08-10 - 2018-09-10

За расчетный период предыдущего месяца (= 8 / август) = @billdate 2018-09-10 это платные пользователи:

Test2 Test3

Однако, когда я изменяюпериод оплаты до 10 октября, это платные пользователи:

Test Test2 Test3

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Если я правильно понимаю вашу логику, платный пользователь - это тот, чей начальный месяц по крайней мере за месяц до текущего месяца, а конечный месяц меньше или равен текущему месяцу.

SELECT *,
    CASE WHEN @billdate >= DATEADD(d, 1, EOMONTH(date_joined)) AND
              (@billdate <= DATEADD(d, 1, EOMONTH(date_left)) OR date_left IS NULL)
         THEN 'billable'
         ELSE 'not billable' END AS status
FROM person;

Эта логика выставления счетов согласуется с тем, что клиенты получают первый месяц бесплатно, но оплачиваются со второго до последнего месяца.

Демо

0 голосов
/ 07 сентября 2018

используйте флаг make, сравнивая месяц и год присоединения с месяцем и годом счета и создавая флаг для каждого пользователя, затем используйте подзапрос для фильтра

  select * from t
(
 select *,case when (month(date_joined)=month(billdate) 
   and  year(date_joined)=year(billdate)) then 'N' else 'Y' end as flag_billable
  from user
) as t where t.flag_billable='Y'

По вашему запросу

DECLARE @billdate AS DATE = '2018-09-01';
select * from 
(
    SELECT * ,case when (month(date_joined)=month(@billdate) 
           and  year(date_joined)=year(@billdate)) then 'N' else 'Y' end as  flag_billable
    FROM person
) t where t.flag_billable='Y'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...