2016-07-20 1 views
0

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

Subscription_ID| Start_Date| End_Date |Monthly_revenue 
2384105  | 1/1/2016 | 6/1/2016 |500 

Я хотел бы, чтобы каким-то образом преобразовать эту строку, чтобы выглядеть следующим образом:

Subscription_ID |Month |Monthly_Revenue 
2384105   |1/1/2016 | 500 
2384105   |2/1/2016 | 500 
2384105   |3/1/2016 | 500 
2384105   |4/1/2016 | 500 
2384105   |5/1/2016 | 500 
2384105   |6/1/2016 | 500 

Я понятия не имею, как даже идти об этом. Любые советы были бы очень признательны или если вы можете указать мне в правильном направлении. Я использую redshift как мою БД, поэтому синтаксис в основном похож на postgres.

Редактировать: Ответить на комментарий - Я могу легко составить таблицу со всеми датами и годами в ней, если это поможет справиться.

+0

Redshift не поддерживает, чтобы генерировать даты рекурсивного CTE в период между любыми 2 указанными датами. У вас есть таблица со всеми месяцами и годами? –

+0

без рекурсивного cte, вы все равно можете сделать это с таблицей подсчета – Matt

+0

Вы бы традиционно делали это в PostgreSQL с помощью 'generate_series()' однако RedShift основан на более старой версии, которая ее не имела. У этого могут быть некоторые альтернативные методы, которые могли бы помочь: http://stackoverflow.com/questions/22759980/generate-series-in-redhsift/34167753#34167753 – Nicarus

ответ

2

Хорошо, я смотрел на какой-то красное смещение документации что-то вроде этого должно работать:

DATEDIFF http://docs.aws.amazon.com/redshift/latest/dg/r_DATEDIFF_function.html

общих табличных выражений http://docs.aws.amazon.com/redshift/latest/dg/r_WITH_clause.html

DATEADD http://docs.aws.amazon.com/redshift/latest/dg/r_DATEADD_function.html

WITH cteData AS (
    SELECT 
     CAST(2384105 AS INTEGER) AS Subscription_ID 
     ,CAST('2016-01-01' AS DATE) AS Start_Date 
     ,CAST('2016-06-01' AS DATE) AS End_Date 
     ,CAST(500 AS INTEGER) AS Monthly_revenue 
) 

,cteTally AS (
     SELECT 0 AS TallyNum 
     UNION ALL 
     SELECT 1 
     UNION ALL 
     SELECT 2 
     UNION ALL 
     SELECT 3 
     UNION ALL 
     SELECT 4 
     UNION ALL 
     SELECT 5 
     UNION ALL 
     SELECT 6 
     UNION ALL 
     SELECT 7 
     UNION ALL 
     SELECT 8 
     UNION ALL 
     SELECT 9 
     UNION ALL 
     SELECT 10 
     UNION ALL 
     SELECT 11 
    ) 


    SELECT 
     Subscription_ID 
     ,DATEADD(month,c.TallyNum,t.Start_date) AS "Month" 
     ,Monthly_revenue 
    FROM 
     cteData t 
     INNER JOIN cteTally c 
     ON DATEDIFF(month,t.Start_Date,t.End_Date) >= c.TallyNum 

это может работать для вас он не использует generate_series() или рекурсивный cte. это PostgresSQL версия, которую я попытался это с SQL Fiddle (http://sqlfiddle.com/#!15/f3a23/7/0) ....

CREATE TABLE Tbl (
    Subscription_ID INTEGER 
    ,Start_Date DATE 
    ,End_Date DATE 
    ,Monthly_revenue INTEGER); 

INSERT INTO Tbl (Subscription_ID, Start_Date, End_Date, Monthly_revenue) 
VALUES (2384105,'2016-01-01','2016-06-01',500); 

WITH cteTally AS (
    SELECT 0 AS TallyNum 
    UNION ALL 
    SELECT 1 
    UNION ALL 
    SELECT 2 
    UNION ALL 
    SELECT 3 
    UNION ALL 
    SELECT 4 
    UNION ALL 
    SELECT 5 
    UNION ALL 
    SELECT 6 
    UNION ALL 
    SELECT 7 
    UNION ALL 
    SELECT 8 
    UNION ALL 
    SELECT 9 
    UNION ALL 
    SELECT 10 
    UNION ALL 
    SELECT 11 
) 

SELECT 
    Subscription_ID 
    ,(t.Start_Date + (c.TallyNum * '1 month'::INTERVAL)) as "Month" 
    ,Monthly_revenue 
FROM 
    Tbl t 
    INNER JOIN cteTally c 
    ON (
     (DATE_PART('year', t.End_Date) - DATE_PART('year', t.Start_Date)) * 12 
     + 
     (DATE_PART('month', t.End_Date) - DATE_PART('month', t.Start_Date)) 
    ) >= c.TallyNum 
; 
+0

спасибо за это. Я не знаком с этими правилами, но я не думаю, что ctetally поддерживается в redshift. От них нет документации по этим функциям – Berra2k

+0

в соответствии с этим документом cteTally, который является общим табличным выражением, должен работать в режиме красного смещения. http://docs.aws.amazon.com/redshift/latest/dg/r_WITH_clause.html, поскольку функции времени даты да, это версия postgressql, ms sql-server на самом деле намного проще для операций с датой. – Matt

+0

AH! Я настолько тупой, что, как я думал, функция была не именем таблицы! спасибо, я попробую это. Также имейте в виду область, в которой у вас есть VALUES() У меня есть тысячи строк с разными значениями, поэтому я могу ссылаться на имена столбцов? – Berra2k

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