Как в журнале записей клиентов найти последнюю метку времени для неуникальных комбинаций идентификаторов? - PullRequest
0 голосов
/ 02 мая 2019

Я работаю с SSMS для запроса базы данных сервера SQL с намерением использовать таблицу истории, чтобы определить самый последний статус отношений между двумя типами сущностей, например, клиенты с многоуровневой подпиской на различные журналы (без подписки, базовая подписка, премиум подписка). Таблица истории содержит идентификатор клиента, идентификатор журнала, метку времени изменения, старое значение подписки и новое значение подписки. Для каждой уникальной комбинации идентификатора клиента и журнала я хочу взять новейшую временную метку и посмотреть на новейшую ценность. Последним шагом будет подсчет количества подписчиков на каждый журнал, и я не заинтересован в разграничении между базовой и премиальной подпиской. Проблема заключается в том, что если пользователь переключается между основной и премиальной подпиской, мой текущий сценарий считает оба изменения и вызывает дубликаты, которые искусственно увеличивают количество подписок.

Я могу видеть необработанные данные и вручную манипулировать ими в требуемом формате, поэтому я доволен данными. Я попытался посмотреть максимальное «измененное время» для каждого клиента, отфильтровав его только по двум базовым и премиальным подпискам, и сгруппировать его по идентификатору клиента, идентификатору журнала и новому статусу подписки. Как уже упоминалось, это вызывает дубликаты:

SELECT MAX(CHANGED_TIME), CUSTOMER_ID, MAGAZINE_ID, OLD_VALUE, NEW_VALUE
FROM CUSTOMER_HISTORY
WHERE (NEW_VALUE=3 or NEW_VALUE=43) 

/* 0 = unsubscribed, 3 = basic subscription, 43 = premium */

GROUP BY CUSTOMER_ID, MAGAZINE_ID, NEW_VALUE
| Time of change | Customer ID | Magazine ID | Old Value | New Value |
|----------------|-------------|-------------|-----------| --------- |
|     today      |       a     |      1      |      3    |     43    |
|   last week    |       a     |      2      |      0    |     3     |
|     today      |       b     |      1      |      43   |     3     |
|   last week    |       b     |      2      |      0    |     3     |
|     today      |       b     |      2      |      3    |     43    |

Я бы хотел построить некоторую логику, которая гласит: «Для каждой уникальной комбинации идентификатора клиента и журнала возвращайте самое последнее новое значение и время изменения», или в этом примере «для клиента b и журнала 2, возвращайте только самые новые». значение'. Это приведет к тому, что предпоследняя строка будет удалена из результата, когда клиент b подписался на журнал 2 - это излишне, потому что он сегодня обновился до премиальной подписки на этот журнал сегодня.

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

Ответы [ 2 ]

0 голосов
/ 02 мая 2019

Использовать оконные функции:

SELECT . . .
FROM (SELECT ch.*,
             ROW_NUMBER() OVER (PARTITION BY CUSTOMER_ID ORDER BY CHANGED_TIME DESC) as seqnum
      FROM CUSTOMER_HISTORY ch
     ) ch
WHERE NEW_VALUE IN (3, 43) AND seqnum = 1;
0 голосов
/ 02 мая 2019

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

SELECT CUSTOMER_ID, MAGAZINE_ID, MAX(CHANGED_TIME) AS [CHANGE_TIME] FROM CUSTOMER_HISTORY
    WHERE (NEW_VALUE = 3) OR (NEW_VALUE = 4)
        GROUP BY CUSTOMER_ID, MAGAZINE_ID

Затем добавьте подзапрос или используйте запрос выше и присоедините его к таблице CUSTOMER_HISTORY дляполучить столбцы NEW_VALUE.

SELECT A.CUSTOMER_ID, A.MAGAZINE_ID, A.CHANGE_TIME, B.NEW_VALUE
    FROM (SELECT CUSTOMER_ID, MAGAZINE_ID, MAX(CHANGED_TIME) AS [CHANGE_TIME] FROM CUSTOMER_HISTORY WHERE (NEW_VALUE = 3) OR (NEW_VALUE = 4) GROUP BY CUSTOMER_ID, MAGAZINE_ID) AS A
        INNER JOIN CUSTOMER_HISTORY AS B
            ON A.CUSTOMER_ID = B.CUSTOMER_ID
            AND A.MAGAZINE_ID = B.MAGAZINE_ID
            AND A.CHANGE_TIME = B.CHANGE_TIME
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...