2016-11-10 21 views
0

試圖尋找答案,閱讀這樣的帖子:SQL Self-join with data comparison for different days 但不能很好理解這將如何在這種情況下工作。是否有可能自我加入要求不同的日期?

希望有任何幫助;

我有一個

  • 用戶ID表(數字)
  • 用戶類型(字符串,說明他們是否會員或客戶)

  • sales_date(時間戳字段)

  • (加上其他欄目,如他們購買的物品和我目前不感興趣的物品的價格)

我想寫一個查詢,它會告訴我每個月有多少人成爲會員和作爲訪客。 因此,我可以回答如下問題: 「9月有多少人在這裏,10月又回來了?」 「9月份會員人數有多少,但在10月降級爲客人?」 「9月有多少人是客人,但在10月升級爲會員?」

1:當需要從同一個表/相同查詢請求2個不同日期範圍時,自加入的方式是什麼?

2:我想我需要請求UserID,然後UserType for Sept和UserType for October。這聽起來正確嗎?不知道如何要求2個不同的日期

SELECT 
     t1.UserID, 
     t1.UserType as UserTypeSept, 
     t2.UserType as UserTypeOct 
    FROM 
     my_table t1 
     join my_table t2 
      on t1.UserID = t2.UserID 
      AND t2.day > '2015-01-01' AND t2.day < '2015-02-01' 
    where 
     t1.day >'2015-02-01' AND t1.day <'2015-03-01' 
; 

我在思考沿着正確的車道? 即使這個工作,它不會告訴我有多少來自「成員」從九月至十月「客人」改變,但至少顯示出2個不同的列中的值

感謝

+0

是您使用的數據庫管理系統,以測試它的樣本數據,您可以刪除評論? –

+0

google bigquery – Bjorn

+0

重要的是,您可以使用投票下方發佈的答案左側的勾號標記接受的答案。請參閱http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work#5235瞭解其重要性。 –

回答

0

我會建議使用分析功能,而不是自我加入,這是更昂貴的。您的數據適合窗口數據。 請運行下面的查詢,然後調整到您的表。 您可能需要格式打印的時間段,並使用CASE子句進行後續月份之間的轉換,如「Member - Guest」到更有意義的名稱。

 WITH 
    members AS ( 
    SELECT 1 AS UserID, 'Member' AS UserType, TIMESTAMP '2015-01-01' AS sales_date 
    UNION ALL SELECT 1 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-02-01' AS sales_date 
    UNION ALL SELECT 2 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-01-01' AS sales_date 
    UNION ALL SELECT 2 AS UserID, 'Member' AS UserType,TIMESTAMP '2015-02-01' AS sales_date 
    UNION ALL SELECT 3 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-01-01' AS sales_date 
    UNION ALL SELECT 3 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-02-01' AS sales_date 
    UNION ALL SELECT 4 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-01-01' AS sales_date 
    UNION ALL SELECT 4 AS UserID, 'Member' AS UserType,TIMESTAMP '2015-02-01' AS sales_date 
    UNION ALL SELECT 5 AS UserID, 'Guest' AS UserType, TIMESTAMP '2016-07-01' AS sales_date 
    UNION ALL SELECT 5 AS UserID, 'Guest' AS UserType, TIMESTAMP '2016-08-01' AS sales_date 
    UNION ALL SELECT 6 AS UserID, 'Member' AS UserType,TIMESTAMP '2016-03-01' AS sales_date 
    UNION ALL SELECT 7 AS UserID, 'Guest' AS UserType, TIMESTAMP '2016-04-01' AS sales_date 
    UNION ALL SELECT 7 AS UserID, 'Guest' AS UserType, TIMESTAMP '2016-05-01' AS sales_date 
    UNION ALL SELECT 8 AS UserID, 'Guest' AS UserType, TIMESTAMP '2016-01-01' AS sales_date 
    UNION ALL SELECT 8 AS UserID, 'Member' AS UserType,TIMESTAMP '2016-02-01' AS sales_date 
    UNION ALL SELECT 9 AS UserID, 'Guest' AS UserType, TIMESTAMP '2016-01-03' AS sales_date 
    UNION ALL SELECT 9 AS UserID, 'Member' AS UserType,TIMESTAMP '2016-02-06' AS sales_date) 
SELECT 
    COUNT(*), 
    member, 
    period, 
    year 
FROM (
    SELECT 
    UserType, 
    UserID, 
    sales_date, 
    FORMAT_DATE("%Y",DATE(sales_date)) AS year, 
    CONCAT(
    FORMAT_DATE("%b",DATE(sales_date)), 
    ' - ', 
    FORMAT_DATE("%b", DATE(LEAD(sales_date,1) OVER (PARTITION BY userId ORDER BY sales_date ASC))) 
    ) AS period, 
    CONCAT(UserType,' - ', LEAD(UserType,1) OVER (PARTITION BY userId ORDER BY sales_date ASC)) AS member 
    FROM 
    members 
    ORDER BY 
    userid) 
WHERE 
    member IS NOT NULL 
    and year = '2016' 
GROUP BY 
year, 
    member, 
    period 
+0

男人,這是一個大的查詢:) – Bjorn

+0

今天會嘗試,非常感謝您花時間來幫助。這個網站真棒! – Bjorn

+0

有沒有辦法按月而不是單日做?它說「TIMESTAMP'2015-02-01'AS sales_date)」可能是ANDYEAR(sales_date)='2015'和MONTH(sales_date)='2'之類的東西? – Bjorn

0

1:是自加入需要索要 從同一個表/同樣的查詢範圍是2個不同的日期時,要走的路?

不是真的!這取決於!在你的情況 - 參見下面的#2

2:我想我要問的用戶ID,那麼用戶類型爲九月VS 用戶類型爲十月

我想下面做你的期望。
請注意:它會在每個月末查找UserType,並將其用作各個月份的用戶類型。

/* 
WITH my_table AS (
    SELECT 1 AS UserID, 'Member' AS UserType, TIMESTAMP '2015-09-01' AS sales_date UNION ALL 
    SELECT 1 AS UserID, 'Member' AS UserType, TIMESTAMP '2015-09-02' AS sales_date UNION ALL 
    SELECT 1 AS UserID, 'Member' AS UserType, TIMESTAMP '2015-09-03' AS sales_date UNION ALL 
    SELECT 1 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-09-10' AS sales_date UNION ALL 
    SELECT 1 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-10-01' AS sales_date UNION ALL 
    SELECT 1 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-10-02' AS sales_date UNION ALL 
    SELECT 2 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-09-01' AS sales_date UNION ALL 
    SELECT 2 AS UserID, 'Member' AS UserType, TIMESTAMP '2015-10-01' AS sales_date UNION ALL 
    SELECT 3 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-09-01' AS sales_date UNION ALL 
    SELECT 3 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-10-01' AS sales_date UNION ALL 
    SELECT 4 AS UserID, 'Guest' AS UserType, TIMESTAMP '2015-09-01' AS sales_date UNION ALL 
    SELECT 4 AS UserID, 'Member' AS UserType, TIMESTAMP '2015-10-01' AS sales_date) 
*/ 
SELECT 
    UserID, 
    MAX(CASE WHEN sales_year_month = '2015-09' THEN UserTypeAtEndOfMonth END) AS UserTypeSept, 
    MAX(CASE WHEN sales_year_month = '2015-10' THEN UserTypeAtEndOfMonth END) AS UserTypeOct 
FROM (
    SELECT 
    UserID, 
    FORMAT_DATE('%Y-%m', DATE(sales_date)) AS sales_year_month, 
    ARRAY_AGG(UserType ORDER BY sales_date DESC LIMIT 1)[OFFSET(0)] AS UserTypeAtEndOfMonth 
    FROM my_table 
    GROUP BY 1, 2 
) 
GROUP BY 1 

如果你想

+0

非常感謝,真的很感謝你的時間! – Bjorn

相關問題