簡體   English   中英

在不同條件下與同一張表連接兩次

[英]Joining with the same table twice with different conditions

我有一個表格,其中包含每天一組產品中用戶活動的暑假。 理論上,每個<UserId, Product, Client, Date>元組只有一行,因為此表是由GROUP BY生成的。 我們稱之為UserActivity

UserActivity:

UserId | Product | Client     | Date
------------------------------------------
John   | Bank    | Mobile App | 2019-02-28
John   | Bank    | Desktop App| 2019-02-28
Sally  | Gym     | Web App    | 2019-02-28

我有另一個表,我們稱它為FirstLastSeen ,其中有UserId以及它們何時首次使用每個ProductClient

FirstLastSeen:

UserId | Product | Client     | Date
------------------------------------------
John   | Bank    | Mobile App | 2019-01-01
John   | Bank    | Desktop App| 2019-02-28
Sally  | Gym     | Web App    | 2019-02-28

我想計算用戶是否是該Product “新手”,以及他們是否是該Client新手。 這意味着他們第一次使用該Product Date等於Date ,而他們第一次使用該Product的日期AND Client等於Date 因此,像這樣的表:

UserId | Product | Client     | Date       | IsNewProduct | IsNewClient
-----------------------------------------------------------------
John   | Bank    | Mobile App | 2019-02-28 | False        | False        // Used on 01-01
John   | Bank    | Desktop App| 2019-02-28 | False        | True         // First time used this client was same day         
Sally  | Bank    | Mobile App | 2019-02-28 | True         | True         // First time we saw her in this product and client

一種方法是:

SELECT 
    UA.UserId, 
    UA.Product, 
    UA.Client, 
    CASE FLS.Date = UA.DATE THEN True ELSE FALSE END AS FirstSeenClient
FROM UserActivity as UA
LEFT JOIN FirstLastSeen AS FLS 
    ON  UA.UserId=FLS.UserId 
    AND UA.Product=FLS.Product 
    AND UA.Client=FLS.Client;

這會給我想要的FirstSeenClient 保證有一行與它們的用法相對應。 我不知道如何獲得FirstSeenProduct 我懷疑答案是在子查詢或窗口函數中,但是我不確定如何寫,可能是MIN(Date) OVER (PARTITION BY UserId, Product) 我對Windowing Functions非常陌生,但這將使我最早看到該Product的用戶Date ,然后可以執行另一個SELECT檢查Date 窗口函數是否可以確保UserId, Product與要針對其進行計算的行相同?

到目前為止,您的查詢看起來不錯。 要檢查這是否是客戶第一次使用產品,可以使用ROW_NUMBER()為具有相同UserId和相同Product (按Date排序)的記錄組中的每個記錄分配一個等級。 當行號為1 ,您知道您正在處理新產品。

SELECT 
    UA.UserId, 
    UA.Product, 
    UA.Client, 
    CASE 
        WHEN ROW_NUMBER() OVER(PARTITION BY UA.UserId, UA.Product ORDER BY UA.Date) = 1 
        THEN true 
        ELSE false 
    END AS IsNewProduct,
    CASE 
        WHEN UA.Date = FLS.Date
        THEN true
        ELSE false
    END AS IsNewClient
FROM UserActivity as UA
LEFT JOIN FirstLastSeen AS FLS 
    ON UA.UserId   = FLS.UserId 
    AND UA.Product = FLS.Product 
    AND UA.Client  = FLS.Client;

DB Fiddle上的演示以及您的示例數據返回:

| UserId | Product | Client      | IsNewProduct | IsNewClient |
| ------ | ------- | ----------- | ------------ | ----------- |
| John   | Bank    | Mobile App  | 1            | 0           |
| John   | Bank    | Desktop App | 0            | 1           |
| Sally  | Gym     | Web App     | 1            | 1           |

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM