Как получить данные подписки на транзакционные данные в Таблице?

У меня есть кусок данных с подписками, выглядящий следующим образом:

customer_name    start_date   end_date     subscription_amount
A                1-7-2017     31-10-2017   4 USD/month
B                1-8-2017     30-09-2017   2 USD/month
C                1-10-2017    30-11-2017   3 USD/month

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

customer_name    payment_date    amount
A                1-7-2017        4 USD
A                1-8-2017        4 USD
A                1-9-2017        4 USD
A                1-10-2017       4 USD
B                1-8-2017        2 USD
B                1-9-2017        2 USD
C                1-10-2017       3 USD
C                1-11-2017       3 USD

Мне нужно сделать это преобразование, чтобы выполнить анализ в таблице, но решения Excel также приемлемы. Я не хочу делать это вручную, скорее, я ищу автоматизированное решение с SQL или Python (я новичок в обоих из них)

2 ответа

Решение

Использование python (вам нужно немного отформатировать данные, чтобы они точно соответствовали вашему Вопросу, но идея здесь) http://rextester.com/OENHUT92986

используйте этот полный список listMonths = [dt.strftime("%Y-%m-01") for dt in rrule(MONTHLY, dtstart=dtstart, until=until) перечислять каждый первый день каждого месяца между 2 датами.

import datetime
import time
from dateutil import parser
from dateutil.rrule import rrule, MONTHLY


data=[
      {"customer_name":"A" ,"start_date":"2017-07-01","end_date":"2017-10-31","subscription_amount":"4 USD/month"},
      {"customer_name":"B" ,"start_date":"2017-08-01","end_date":"2017-09-30","subscription_amount":"2 USD/month"},
      {"customer_name":"C" ,"start_date":"2017-10-01","end_date":"2017-11-30","subscription_amount":"3 USD/month"}
     ]

for datum in data :
    dtstart=parser.parse(datum["start_date"])
    until=parser.parse(datum["end_date"])

    listMonths = [dt.strftime("%Y-%m-01") for dt in rrule(MONTHLY, dtstart=dtstart, until=until)]

    for month in listMonths :    
         print datum["customer_name"],month,datum["subscription_amount"]

будет производить:

A 2017-07-01 4 USD/month
A 2017-08-01 4 USD/month
A 2017-09-01 4 USD/month
A 2017-10-01 4 USD/month
B 2017-08-01 2 USD/month
B 2017-09-01 2 USD/month
C 2017-10-01 3 USD/month
C 2017-11-01 3 USD/month

Здесь запрос в MS-SQL

if object_id('tempdb..# подписки') НЕ НУЛЯЕТ ТАБЛИЦУ УДАЛЕНИЯ # подписки if object_id('tempdb..# Календарь') НЕ НУЛЯЕТ ТАБЛИЦУ УДАЛЕНИЯ #Calendar

объявить @min_date как дату объявить @max_date как дату

создать таблицу # подписки (имя клиента, дата начала, дата окончания, подписка на деньги, currencyPeriod varchar(10))

создать таблицу #Calendar ( Date_f date)

вставьте в значения # подписок ('A',CAST('2017-7-01 00:00:00.000' в качестве даты),CAST('2017-07-10 00:00:00.000' в качестве даты),4,'USD/month') вставить в значения #subscription ('B',CAST('2017-8-01 00:00:00.000'как дата),CAST('2017-08-04 00:00:00.000'как дата),2, "USD / month") вставить в значения #subscription ("C", CAST ("2017-10-01 00:00:00" в качестве даты), CAST ("2017-10-02 00:00:00.000") в качестве даты),3, "долл. США / месяц")

--- здесь нам нужно получить минимальную и максимальную дату всех регистров. set @min_date = (выберите MIN (начальная дата) ОТ # подписок) установите @max_date = (выберите МАКС (конечная дата) ОТ # подписок)

- Здесь мы создаем временный календарь с учетом минимальной и максимальной даты всех регистров.

WHILE @min_date <= @max_date НАЧАТЬ ВСТАВИТЬ В #Calendar (Date_f) ВЫБРАТЬ @min_date

SET @min_date = DATEADD (день, 1, @ min_date) END

- ВЫБОР РЕЗУЛЬТАТОВ ВЫБОР B.customer_name,A.Date_f как 'payment_date', CONCAT(CAST(subscription_amount as int),' ','USD') как 'subscription_amount'
ИЗ #Calendar A INNER JOIN # подписки B ON A.Date_f МЕЖДУ startdate И end_date

Другие вопросы по тегам