嵌套JOIN遇到问题

时间:2018-02-15 23:24:34

标签: mysql sql

所以我正在尝试组合一些查询,而且我遇到了一个问题:

SELECT OFFERS.ID AS ID, OFFERS.NAME as NAME, PROGRAM_ID, OFFER_TYPE, DATE_CREATED, PROGRAMS.NAME as PROGRAM_NAME, CLICKS_IN, CLICKS_OUT, SALES 
FROM 
    (OFFERS INNER JOIN PROGRAMS ON PROGRAMS.ID = OFFERS.PROGRAM_ID) 
        INNER JOIN 
    (SELECT COUNT(*) AS CLICKS_IN FROM CLICKS_IN WHERE OFFER = ID)a 
        INNER JOIN 
    (SELECT COUNT(*) AS CLICKS_OUT FROM CLICKS_OUT WHERE OFFER = ID)b
        INNER JOIN 
    (SELECT SUM(REVENUE) AS SALES FROM CONVERSIONS WHERE LOCAL_OFFER = ID)c
WHERE OFFER_ACTIVE = 1 AND OFFERS.USER_GROUP = ?

我希望OFFER = ID查询使用OFFERS.ID AS ID中的值,但我很难理解如何实现它。

1 个答案:

答案 0 :(得分:1)

我认为你的初始括号只是让事情有点混淆,你正在使用的选择类型更适合SELECTs表达式列表中的子查询;试试这种方式:

SELECT OFFERS.ID AS ID, OFFERS.NAME as NAME, PROGRAM_ID, OFFER_TYPE
   , DATE_CREATED, PROGRAMS.NAME as PROGRAM_NAME, CLICKS_IN, CLICKS_OUT, SALES 
FROM OFFERS 
   INNER JOIN PROGRAMS ON PROGRAMS.ID = OFFERS.PROGRAM_ID 
   INNER JOIN 
    (SELECT OFFER, COUNT(*) AS CLICKS_IN FROM CLICKS_IN GROUP BY OFFER) AS a 
    ON a.OFFER = OFFERS.ID
   INNER JOIN 
    (SELECT OFFER, COUNT(*) AS CLICKS_OUT FROM CLICKS_OUT GROUP BY OFFER) AS b 
    ON b.OFFER = OFFERS.ID
   INNER JOIN 
    (SELECT LOCAL_OFFER, SUM(REVENUE) AS SALES FROM CONVERSIONS GROUP BY LOCAL_OFFER) AS c
    ON c.LOCAL_OFFER = OFFERS.ID
WHERE OFFER_ACTIVE = 1 AND OFFERS.USER_GROUP = ?

与相关子查询(引用外部查询的子查询)相反,此方法往往更有效,除非子查询中涉及的表非常大,和/或您预计结果很少到底。在这种情况下,您的原始子查询几乎可以“按原样”移动到SELECT子句:

SELECT o.ID AS ID, o.NAME as NAME, PROGRAM_ID, OFFER_TYPE, DATE_CREATED, PROGRAMS.NAME as PROGRAM_NAME
   , (SELECT COUNT(*) FROM CLICKS_IN AS t WHERE t.OFFER = o.ID) AS CLICKS_IN
   , (SELECT COUNT(*) FROM CLICKS_OUT AS t WHERE t.OFFER = o.ID) AS CLICKS_OUT
   , (SELECT SUM(REVENUE) FROM CONVERSIONS AS t WHERE t.LOCAL_OFFER = o.ID) AS SALES 
FROM OFFERS AS o INNER JOIN PROGRAMS ON PROGRAMS.ID = o.PROGRAM_ID 
WHERE OFFER_ACTIVE = 1 AND o.USER_GROUP = ?

旁注:在涉及多个表的查询中,最好完全限定使用的任何字段名称。 (例如,我无法确定这些字段的来源:PROGRAM_ID,OFFER_TYPE,DATE_CREATED,OFFER_ACTIVE)。