【问题标题】:LEFT JOIN 3rd Table to the original Table rather than the resultant tableLEFT JOIN 3rd Table 到原始表而不是结果表
【发布时间】:2017-05-11 20:14:29
【问题描述】:

我有两张表,例如

  1. 收入(点、日期、公司)
  2. 结果(点、日期、出)

其中 pointdate 是主键。
我需要找出任何给定日期的总收入inc 和结果out。 我的回答

WITH all_date AS
(SELECT point, date FROM income
UNION
SELECT point, date FROM outcome)
SELECT a.point, a.date, SUM(inc), SUM(out)
FROM all_date a LEFT JOIN income i ON i.point=a.point AND i.date=d.date
                LEFT JOIN outcome o ON o.point=a.point AND o.date=a.date
GROUP BY a.point, a.date

但是我得到了错误的结果。因为all_date LEFT JOIN income 在尝试使用outcome 执行LEFT JOIN 时会复制income 中的某些行,因此会弄乱最终的SUM

基本上我想LEFT JOIN 第三张桌子outcomeall_date 不是 all_date LEFT JOIN income。请参阅http://www.sql-ex.ru/learn_exercises.php 的 Qus No 30. 以获得进一步的说明

【问题讨论】:

    标签: mysql sql outer-join


    【解决方案1】:

    那为什么不先加入呢?

    或者更好的是,只做一个完整的外连接:

    Select coalesce(o.point, i.point) point,
       coalesce(o.Date, i.date) date
    From income i full join outcome o
      on o.point=i.point 
         and o.date=i.date
    group by coalesce(o.point, i.point),
         coalesce(o.Date, i.date)
    

    而且,由于您实际上没有使用任何聚合函数,因此 distinct 也可以:

    Select distinct
       coalesce(o.point, i.point) point,
       coalesce(o.Date, i.date) date
    From income i full join outcome o
      on o.point=i.point 
         and o.date=i.date
    

    抱歉,我不是 MySQL 专家,也没有意识到 MySQL 没有 Full Join 语法。但有一个解决方法。请看以下链接:

    Full Join in MYSQL

    基本上你需要一个联合,(实际上接近你所做的)

    select point, date 
    from income i
     left join outcome o 
        on o.point=i.point 
          and o.date=i.date  
      UNION                 -- <-- leave out the ALL to eliminate duplicates
    select point, date 
    from outcome o
     right join income i 
        on i.point=o.point 
          and i.date=o.date  
    

    【讨论】:

    • 刚刚意识到 MySQL 不支持 FULL JOIN。有什么解决办法吗?
    • 抱歉,我不是 MySQL 专家,也没有意识到这一点。但是请检查一下...如我的答案中的链接中所述
    • @BikashBehera 不要让人们感到困惑 - 你用 MS SQL SERVER dbms 标记了旅游问题。
    • @IvanStarostin 是的,很抱歉。实际上,我同时标记了 MSSQL 和 MySQL,因为练习是在 MSSQL 中进行的,我试图在我的 PC 上使用 MySQL 解决练习。然后最初的问题编辑器稍后删除了 mysql 标签。
    【解决方案2】:

    这是我在 MSSQL 中的最终解决方案。但我想使用COALESCEFULL JOIN 效果最好。

        WITH all_date AS
        (SELECT point, date FROM income
        UNION
        SELECT point, date FROM outcome)
    
        SELECT a.point, a.date,
        (SELECT SUM(o.out) FROM outcome o WHERE o.point=a.point AND o.date=a.date) AS outcome,
        (SELECT SUM(i.inc) FROM income i WHERE i.point=a.point AND i.date=a.date) AS income
    
        FROM all_date a
    

    【讨论】:

      【解决方案3】:

      MS-SQL sp 解决您的问题:

      CREATE PROCEDURE dototals
      @date DATETIME
      AS
      BEGIN
      
      SELECT point,SUM(ISNULL(inc,0)) as inc into #tmp_i FROM Income WHERE date =@date  GROUP BY point
      
      SELECT point,SUM(ISNULL(out,0)) as out into #tmp_d FROM Outcome WHERE date =@date  GROUP BY point
      
      SELECT DISTINCT point into #tmp_p FROM 
      (SELECT point FROM #tmp_i
      UNION ALL
      SELECT point FROM #tmp_o)
      
      SELECT @date as date, t1.point as point, t2.out as outcome,t3.inc as income 
      FROM #tmp_p as t1
      LEFT JOIN #tmp_o as t2 on t1.point=t2.point
      LEFT JOIN #tmp_i as t3 on t1.point=t3.point
      END
      

      【讨论】:

        【解决方案4】:

        不知道这里用表表达式的目的是什么,这里用一个join就可以得到结果:

        SELECT i.point, i.date, SUM(inc), SUM(out)
        FROM  income i 
        LEFT JOIN outcome o   
        ON o.point=i.point AND o.date=i.date
        GROUP BY i.point, i.date
        

        【讨论】:

        • 单向外连接将跳过一侧的行。
        • @LONG 在您的查询中,您将从右表outcome 中删除在左表income 中不匹配的行。为了获得所有point-date,我使用了 CTE
        • 我明白了,如果您只想过滤掉那些常见日期,请使用INNER JOIN。只需在我的回答中将LEFT JOIN 更改为INNER JOIN。而且,根据您的评论,我猜您不想错过任何日期,无论incout 都存在,然后尝试:SELECT i.point, i.date, SUM(ISNULL(i.inc ,0)), SUM(ISNULL(o.out,0)) 从收入 i FULL JOIN 结果 o ON o.point=i.point AND o.date=i.date GROUP BY i.point, i.date跨度>
        猜你喜欢
        • 2016-09-14
        • 2012-03-27
        • 2020-01-13
        • 1970-01-01
        • 2014-11-14
        • 1970-01-01
        • 1970-01-01
        • 2021-06-25
        • 2018-12-04
        相关资源
        最近更新 更多