bugfix> sql > 投稿

サブクエリのヘルプが必要です。 問題を単純化するために

顧客テーブルがあります(一意の顧客のみがいます)

Cust ID, Cust Name

セールステーブルがあります(顧客に対して複数のエントリがあります)

SaleID, CustID, DatePurchase, Amount

すべての顧客を返品したいが、最新の購入のみを表示したい

John Smith     02/05/2018
Jane Smith     02/10/2018

私は誰かに結合を使用したい....

回答 5 件
  • OUTER APPLY (Oracle 12c) を使用できます :

    SELECT *
    FROM Cust c
    OUTER APPLY (SELECT *
                 FROM Sales s
                 WHERE c.cust_id = s.sales_id
                 ORDER BY s.DatePurchase DESC
                 FETCH FIRST 1 ROW ONLY) sub;
    
    

    代わりに:

    WITH cte AS (
      SELECT c.*,s.Amount, s.DatePurchase, s.SaleId
         ROW_NUMBER() OVER(PARTITION BY c.Cust_id ORDER BY s.DatePurchase DESC) AS rn
      FROM Cust c
      LEFT JOIN Sales s
        ON c.Cust_id = s.Cust_id
    )
    SELECT *
    FROM cte
    WHERE rn = 1;
    
    

  • 私は ROW_NUMBER を使用します  ここに:

    SELECT CustID, CustName, SaleID, DatePurchase, Amount
    FROM
    (
        SELECT c.*, s.SaleID, s.DatePurchase, s.Amount,
            ROW_NUMBER() OVER (PARTITION BY c.CustID ORDER BY s.DatePurchase DESC) rn
        FROM customer c
        LEFT JOIN sales s
            ON c.CustID = s.CustID
    ) t
    WHERE t.rn = 1;
    
    

    販売レコードをまったく持たない顧客は NULL を持つことに注意してください  販売ID、購入日、および金額について報告されます。 COALESCE を使用して、これらをプレースホルダーに置き換えることができます 、 必要に応じて。

  • 他の回答に加えて、 dense_rank を使用するオプションもあります  構築します。

    あなたの場合:

    select c.CustID, max(s.DatePurchase) keep (dense_rank FIRST order by s.DatePurchase desc) 
    from customers c
    LEFT JOIN sales s on s.CustID = c.CustID
    group by c.CustID;
    
    

  • 以下のように簡単なサブクエリを使用することもできます

    SELECT c.Cust_Name,
        s.DatePurchase
    FROM customer c
    INNER JOIN sales s
    INNER JOIN (SELECT Cust_ID, 
                MAX(DatePurchase) dpur 
                FROM sales GROUP BY Cust_ID) s1 ON s1.Cust_ID = s.Cust_ID
        AND s1.dpur = s.DatePurchase
    
    

  • 最新の購入日だけが必要な場合は、 JOIN を使用してください  および GROUP BY

    SELECT c.CustName, MAX(s.DatePurchase)
    FROM customer c INNER JOIN
         sales s
         ON c.custid = s.custid
    GROUP BY c.custid, c.custname;
    
    

あなたの答え