代码之家  ›  专栏  ›  技术社区  ›  Hosam Aly

查询中的左右联接

  •  0
  • Hosam Aly  · 技术社区  · 16 年前

    一位朋友向我寻求帮助,帮助我建立一个查询,该查询将显示每个模型在一个月的每一天售出了多少件,当某一天某个特定模型没有售出任何一件产品时,即使那天没有任何模型的产品售出,也会显示零。我提出了下面的查询,但它没有按预期工作。我只拿到已经售出的车型的记录,我不知道为什么。

    select days_of_months.`Date`,
           m.NAME as "Model",
           count(t.ID) as "Count"
      from MODEL m
      left join APPLIANCE_UNIT a on (m.ID = a.MODEL_FK and a.NUMBER_OF_UNITS > 0)
      left join NEW_TICKET t on (a.NEW_TICKET_FK = t.ID and t.TYPE = 'SALES'
    and t.SALES_ORDER_FK is not null)
     right join (select date(concat(2009,'-',temp_months.id,'-',temp_days.id)) as "Date"
                   from temp_months
                  inner join temp_days on temp_days.id <= temp_months.last_day
                  where temp_months.id = 3 -- March
                 ) days_of_months on date(t.CREATION_DATE_TIME) =
    date(days_of_months.`Date`)
     group by days_of_months.`Date`,
           m.ID, m.NAME
    

    我已经创建了临时表 temp_months temp_days 以获得任何月份的所有天数。我使用的是MySQL5.1,但我试图使查询符合ANSI。

    3 回复  |  直到 16 年前
        1
  •  6
  •   Quassnoi    16 年前

    你应该 CROSS JOIN 您的日期和型号,这样无论什么,您每天的型号对都有一个记录,然后 LEFT JOIN 其他表格:

    SELECT  date, name, COUNT(t.id)
    FROM    (
            SELECT ...
            ) AS days_of_months
    CROSS JOIN
            model m
    LEFT JOIN
            APPLIANCE_UNIT a
    ON      a.MODEL_FK = m.id
            AND a.NUMBER_OF_UNITS > 0
    LEFT JOIN
            NEW_TICKET t
    ON      t.id = a.NEW_TICKET_FK
            AND t.TYPE = 'SALES'
            AND t.SALES_ORDER_FK IS NOT NULL
            AND t.CREATION_DATE_TIME >= days_of_months.`Date`
            AND t.CREATION_DATE_TIME < days_of_months.`Date` + INTERVAL 1 DAY
    GROUP BY
            date, name
    

    你现在做的方式就是 NULL 在里面 model_id 在你没有销售的日子里,他们被分组在一起。

    注意 JOIN 条件:

    AND t.CREATION_DATE_TIME >= days_of_months.`Date`
    AND t.CREATION_DATE_TIME < days_of_months.`Date` + INTERVAL 1 DAY
    

    而不是

    DATE(t.CREATION_DATE_TIME) = DATE(days_of_months.`Date`)
    

    这将有助于您查询 sargable (按索引优化)

        2
  •  0
  •   simon    16 年前

    您需要使用外部联接,因为它们不需要两个联接表中的每个记录都有匹配的记录。

    http://dev.mysql.com/doc/refman/5.1/en/join.html

        3
  •  0
  •   Remus Rusanu    16 年前

    你在找一个 OUTER 加入。左外部联接创建一个结果集,其中包含联接左侧的记录,即使右侧没有要联接的记录。右外部联接在相反的方向上执行相同的操作,即使左侧没有相应的记录,也会为右侧表创建一个记录。从没有记录的表中投影的任何列在联接结果中将具有空值。