简体   繁体   English

与多个嵌套选择的左联接

[英]LEFT JOIN with multiple nested select

The following statement surprisingly works, but I'm not sure joining the same table 3 times is efficient. 以下语句出人意料地起作用,但是我不确定3次加入同一张表是否有效。 I had to disable ONLY_FULL_GROUP_BY in order for it to work. 我必须禁用ONLY_FULL_GROUP_BY才能使其正常运行。

There are 2 tables in play. 有2张桌子在玩。 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). 一个是包含Distributor信息的主表,第二个是包含主表(assoc)中关联的Distributor的amountdateid的购买表。

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. 用户需要能够按这些值( lysytd等)进行过滤,因此将它们作为变量连接似乎是一种方法。 The DB size is about 7,000 records. 数据库大小约为7,000条记录。

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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