代码之家  ›  专栏  ›  技术社区  ›  Majesty

SQL:如何为每个客户选择上次购买的产品?

  •  2
  • Majesty  · 技术社区  · 2 年前

    考虑以下表格结构:

    • invoice :id,client_id
    • items :id,invoice_id,名称,日期

    我的目标是获得以下数据集: client_id, name, date 但是名称和日期是与最后购买的产品相对应的列。

    我尝试了以下查询,但没有产生正确的结果

    SELECT 
        i.client_id, ii.name, MAX(ii.date) 
    FROM
        invoice i
    INNER JOIN
        invoice_item ii ON i.id = ii.invoice_id
    GROUP BY
        i.client_id;
    
    1 回复  |  直到 2 年前
        1
  •  2
  •   marc_s MisterSmith    2 年前

    您没有提到您正在使用的RDBMS——如果它确实支持CTE(Common Table Expressions)和窗口函数(许多最常用的RDBMS都支持它),那么您可以使用以下内容:

    WITH Purchases AS
    (
        SELECT 
            i.client_id, ii.name, ii.date,
            RowNum = ROW_NUMBER() OVER (PARTITION BY i.client_id ORDER BY ii.date DESC)
        FROM
            invoice i
        INNER JOIN
            invoice_item ii ON i.id = ii.invoice_id
    )
    SELECT
        p.client_id, p.name, p.date
    FROM
        Purchases
    WHERE
        p.RowNum = 1;
        
    

    这个 Purchases 是一个CTE——有点像“一次性的内联视图”;使用 ROW_NUMBER 函数,您可以通过 client_id ,并且每个客户的所有购买都是按顺序编号的,按购买日期降序排列,因此每个客户的最新购买总是 RowNum = 1 -这正是我从CTE中选择的。