【问题标题】:Join two tables on the same date or closest date (before or after)在同一日期或最接近的日期(之前或之后)加入两个表
【发布时间】:2014-12-12 11:33:49
【问题描述】:

我刚从 Gord Thompson 那里得到了关于类似问题 (Combine two tables by joining on the same date or closest prior date (not just exact matches)) 的大力帮助,但现在意识到我的数据不是我所期望的。事实证明,我的 Lead_Dates 可以晚于 Product_Interest_Dates,这导致之前的 SQL 代码放弃了这些情况。更具体地说:

我有两张桌子:

  • 客户 ID
  • Lead_Date
  • Lead_Source

  • 客户 ID
  • Product_Interest_Date
  • Product_Interest

我想要两个创建一个表,其中对于每个 CustomerID,每个 Product_Interest 都连接到最接近日期的 Lead_Source(之前或之后)。决赛桌将是:

CustomerID
Product_Interest_Date
Product_Interest
Lead_Date (the closest entry in time to Product_Interest_Date)
Lead_Source (the Lead_Source of the closest Lead_Date)

我研究了 Gord 的代码,但无法将其带回家。按照他的例子,我想要这个:http://i.stack.imgur.com/4ZVDV.jpg

序列的 SQL 堆栈溢出新 1

SELECT
pi.CustomerID, 
pi.Product_Interest_Date,
l.Lead_Date, 
Abs(pi.Product_Interest_Date-l.Lead_Date) AS Date_Gap

FROM 
Test_PI pi
INNER JOIN 
Test_Leads l

堆栈溢出新 2

SELECT 
[Stack Overflow NEW 1].CustomerID,
[Stack Overflow NEW 1].Product_Interest_Date, 
Min([Stack Overflow NEW 1].Date_Gap) AS MinOfDate_Gap
FROM [Stack Overflow NEW 1]
GROUP BY [Stack Overflow NEW 1].CustomerID, 
[Stack Overflow NEW 1].Product_Interest_Date;

决赛

SELECT Test_PI.CustomerID, 
       Test_PI.Product_Interest_Date, 
       Test_PI.Product_Interest, 
       Test_Leads.Lead_Date, 
       Test_Leads.Lead_Source
FROM (Test_PI INNER JOIN ([Stack Overflow NEW 2] 
 INNER JOIN [Stack Overflow NEW 1] 
   ON ([Stack Overflow NEW 2].CustomerID = [Stack Overflow NEW 1].CustomerID) 
    AND ([Stack Overflow NEW 2].Product_Interest_Date = [Stack Overflow NEW 1].Product_Interest_Date) 
    AND ([Stack Overflow NEW 2].MinOfDate_Gap = [Stack Overflow NEW 1].Date_Gap)) 
  ON (Test_PI.CustomerID = [Stack Overflow NEW 2].CustomerID) 
   AND (Test_PI.Product_Interest_Date = [Stack Overflow NEW 2].Product_Interest_Date))
 INNER JOIN Test_Leads 
 ON ([Stack Overflow NEW 1].CustomerID = Test_Leads.CustomerID) 
  AND ([Stack Overflow NEW 1].Lead_Date = Test_Leads.Lead_Date)
GROUP BY Test_PI.CustomerID, Test_PI.Product_Interest_Date, Test_PI.Product_Interest, Test_Leads.Lead_Date, Test_Leads.Lead_Source;

我试图将所有这些组合成一个代码,但无法通过 SQL FROM 错误!这是我的具体问题,如何在单个 SQL 代码中编写?

SELECT 
Test_PI.CustomerID,
Test_PI.Product_Interest_Date,
Test_PI.Product_Interest,
Test_Leads.Lead_Date,
Test_Leads.Lead_Source
FROM
(Test_PI 
INNER JOIN
   ( (SELECT 
             latest.CustomerID, 
             latest.Product_Interest_Date, 
             Min(latest.Date_Gap) AS Min_Date_Gap
      FROM 
           latest 
     ) latest1
INNER JOIN
  (SELECT 
             pi.CustomerID, 
             pi.Product_Interest_Date, 
             l.Lead_Date,
             Abs(pi.Product_Interest_Date - l.Lead_Date) AS Date_Gap
      FROM 
            Test_PI pi 
       INNER JOIN 
            Test_Leads l
       ON pi.CustomerID = l.CustomerID 
    ) latest
   ) 
 ON Test_PI.CustomerID = latest1.CustomerID AND Test_PI.Product_Interest_Date = latest1.Product_Interest_Date

INNER JOIN 
  Test_Leads
    ON Test_Leads.CustomerID = latest1.CustomerID
        AND Test_Leads.Lead_Date = latest1.Lead_Date

【问题讨论】:

    标签: sql ms-access join


    【解决方案1】:

    现在我们正在考虑过去和未来的 [Lead_Date] 值,我已经调整了测试数据以涵盖一个特殊情况

    表:Test_PI

    CustomerID  Product_Interest_Date  Product_Interest
    ----------  ---------------------  ----------------
             1  2014-09-07             Interest1       
             1  2014-09-08             Interest2       
             1  2014-09-15             Interest3       
             1  2014-09-28             Interest4       
    

    表:Test_Leads

    CustomerID  Lead_Date   Lead_Source
    ----------  ----------  -----------
             1  2014-09-07  Source1    
             1  2014-09-14  Source2    
             2  2014-09-15  Source3    
             1  2014-09-16  Source4    
    

    我们将首先创建一个名为 [Date_Gaps] 的已保存 Access 查询

    SELECT
        pi.CustomerID, 
        pi.Product_Interest_Date,
        l.Lead_Date,
        Abs(DateDiff("d", pi.Product_Interest_Date, l.Lead_Date)) AS Date_Gap
    FROM 
        Test_PI pi
        INNER JOIN 
        Test_Leads l
            ON pi.CustomerID = l.CustomerID
    

    返回

    CustomerID  Product_Interest_Date  Lead_Date   Date_Gap
    ----------  ---------------------  ----------  --------
             1  2014-09-07             2014-09-07         0
             1  2014-09-08             2014-09-07         1
             1  2014-09-15             2014-09-07         8
             1  2014-09-28             2014-09-07        21
             1  2014-09-07             2014-09-14         7
             1  2014-09-08             2014-09-14         6
             1  2014-09-15             2014-09-14         1
             1  2014-09-28             2014-09-14        14
             1  2014-09-07             2014-09-16         9
             1  2014-09-08             2014-09-16         8
             1  2014-09-15             2014-09-16         1
             1  2014-09-28             2014-09-16        12
    

    现在查询

    SELECT 
        CustomerID,
        Product_Interest_Date,
        Min(Date_Gap) AS MinOfDate_Gap
    FROM Date_Gaps
    GROUP BY
        CustomerID, 
        Product_Interest_Date
    

    返回

    CustomerID  Product_Interest_Date  MinOfDate_Gap
    ----------  ---------------------  -------------
             1  2014-09-07                         0
             1  2014-09-08                         1
             1  2014-09-15                         1
             1  2014-09-28                        12
    

    所以如果我们简单地加入 [Date_Gaps] 查询以获取 [Lead_Date]

    SELECT
        mingap.CustomerID,
        mingap.Product_Interest_Date,
        Date_Gaps.Lead_Date
    FROM
        Date_Gaps
        INNER JOIN
        (
            SELECT 
                CustomerID,
                Product_Interest_Date,
                Min(Date_Gap) AS MinOfDate_Gap
            FROM Date_Gaps
            GROUP BY
                CustomerID, 
                Product_Interest_Date
        ) mingap
            ON Date_Gaps.CustomerID = mingap.CustomerID
                AND Date_Gaps.Product_Interest_Date = mingap.Product_Interest_Date
                AND Date_Gaps.Date_Gap = mingap.MinOfDate_Gap
    

    我们得到

    CustomerID  Product_Interest_Date  Lead_Date 
    ----------  ---------------------  ----------
             1  2014-09-07             2014-09-07
             1  2014-09-08             2014-09-07
             1  2014-09-15             2014-09-14
             1  2014-09-15             2014-09-16
             1  2014-09-28             2014-09-16
    

    请注意,我们在 09-15 获得了两次点击,因为它们都有 1 天的间隔(之前和之后)。因此,我们需要通过使用Min(Lead_Date)(或Max(Lead_Date),您的选择)将上述查询包装在聚合查询中来打破这种联系

    SELECT
        CustomerID,
        Product_Interest_Date,
        Min(Lead_Date) AS MinOfLead_Date
    FROM
        (
            SELECT
                mingap.CustomerID,
                mingap.Product_Interest_Date,
                Date_Gaps.Lead_Date
            FROM
                Date_Gaps
                INNER JOIN
                (
                    SELECT 
                        CustomerID,
                        Product_Interest_Date,
                        Min(Date_Gap) AS MinOfDate_Gap
                    FROM Date_Gaps
                    GROUP BY
                        CustomerID, 
                        Product_Interest_Date
                ) mingap
                    ON Date_Gaps.CustomerID = mingap.CustomerID
                        AND Date_Gaps.Product_Interest_Date = mingap.Product_Interest_Date
                        AND Date_Gaps.Date_Gap = mingap.MinOfDate_Gap
        )
    GROUP BY
        CustomerID,
        Product_Interest_Date
    

    给我们

    CustomerID  Product_Interest_Date  MinOfLead_Date
    ----------  ---------------------  --------------
             1  2014-09-07             2014-09-07    
             1  2014-09-08             2014-09-07    
             1  2014-09-15             2014-09-14    
             1  2014-09-28             2014-09-16    
    

    所以现在我们准备加入原始表

    SELECT 
        Test_PI.CustomerID,
        Test_PI.Product_Interest_Date,
        Test_PI.Product_Interest,
        Test_Leads.Lead_Date,
        Test_Leads.Lead_Source
    FROM
        (
            Test_PI
            INNER JOIN
            (
                SELECT
                    CustomerID,
                    Product_Interest_Date,
                    Min(Lead_Date) AS MinOfLead_Date
                FROM
                    (
                        SELECT
                            mingap.CustomerID,
                            mingap.Product_Interest_Date,
                            Date_Gaps.Lead_Date
                        FROM
                            Date_Gaps
                            INNER JOIN
                            (
                                SELECT 
                                    CustomerID,
                                    Product_Interest_Date,
                                    Min(Date_Gap) AS MinOfDate_Gap
                                FROM Date_Gaps
                                GROUP BY
                                    CustomerID, 
                                    Product_Interest_Date
                            ) mingap
                                ON Date_Gaps.CustomerID = mingap.CustomerID
                                    AND Date_Gaps.Product_Interest_Date = mingap.Product_Interest_Date
                                    AND Date_Gaps.Date_Gap = mingap.MinOfDate_Gap
                    )
                GROUP BY
                    CustomerID,
                    Product_Interest_Date
            ) closest
                ON Test_PI.CustomerID = closest.CustomerID
                    AND Test_PI.Product_Interest_Date = closest.Product_Interest_Date
        )
        INNER JOIN
        Test_Leads
            ON Test_Leads.CustomerID = closest.CustomerID
                AND Test_Leads.Lead_Date = closest.MinOfLead_Date
    

    返回

    CustomerID  Product_Interest_Date  Product_Interest  Lead_Date   Lead_Source
    ----------  ---------------------  ----------------  ----------  -----------
             1  2014-09-07             Interest1         2014-09-07  Source1    
             1  2014-09-08             Interest2         2014-09-07  Source1    
             1  2014-09-15             Interest3         2014-09-14  Source2    
             1  2014-09-28             Interest4         2014-09-16  Source4    
    

    【讨论】:

    • 也感谢 Gord 跟进这件事。您的答案非常完整且具有教育意义。
    猜你喜欢
    • 2017-02-28
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 2020-06-30
    • 2014-12-11
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    相关资源
    最近更新 更多