简体   繁体   中英

LEFT JOIN with multiple nested select

The following statement surprisingly works, but I'm not sure joining the same table 3 times is efficient. I had to disable ONLY_FULL_GROUP_BY in order for it to work.

There are 2 tables in play. One is the main table with Distributor information, the second is a table of purchases that contains the amount , date , and id of the associated Distributor in the main table (assoc).

There are 3 things I needed. Year to date sales, which SUMS the amount of a certain Distributor's sales from the current year. Last year sales, which does the same for the previous year. Then finally just get the latest purchase date and amount.

The user needs to be able to filter by these values ( lys , ytd , etc...) so joining them as variables seems like the way to go. The DB size is about 7,000 records.

SELECT 
    d.*,
    ytd_total,
    lys_total,
    last_amount,
    last_purchase

FROM Distributor as d
LEFT JOIN (
    SELECT
        assoc, SUM(amount) ytd_total
        FROM purchases
        WHERE db = 1 AND purchase_date >= '{$year}-01-01'
        GROUP BY assoc
) AS ytd
ON ytd.assoc = d.id

LEFT JOIN (
    SELECT
        assoc, SUM(amount) lys_total
        FROM purchases
        WHERE db = 1 AND purchase_date BETWEEN '{$lyear}-01-01' AND '{$lyear}-12-31'
        GROUP BY assoc
) AS lys
ON lys.assoc = d.id

LEFT JOIN (
    SELECT
        assoc, amount last_amount, purchase_date last_purchase
        FROM purchases
        WHERE db = 1
        GROUP BY assoc
) AS lst
ON lst.assoc = d.id

WHERE ........

You can do more work in each aggregation query. I think this is more whatyou want:

select d.*, pa.ytd_total, pa.lys_total, pa.last_purchase_date, p.amount
from distributor d left join
     (select p.assoc,
             sum(case when p.purchase_date >= '{$year}-01-01' then p.amount end) as ytd_total,
             sum(case when p.purchase_date BETWEEN '{$lyear}-01-01' AND '{$lyear}-12-31' then p.amount end) as lys_total,
             max(p.purchase_date) as last_purchase_date             
      from purchases p
      where p.db = 1
      group by p.assoc
     ) pa left join
     purchases p
     on pa.assoc = p.assoc and pa.last_purchase_date = p.purchase_date;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM