0

我想知道MySQL中Full Outer Join的替代方案。我知道这可以通过联合来完成,但它不起作用,因为我的要求并不复杂,我希望如此。我有两个表 master(branch_id,purchase_mindate,purchase_billvalue) 和 transfer(branch_id,tra_gtr_date,tra_travalue) ,其中两个 id 字段几乎相同。现在我需要通过将两个表与条件连接来获取值id,sum(billvalue),sum(travalue)

  1. Mindate=当前日期
  2. Gtrdate=当前日期
  3. 如果主表没有任何值但传输表包含,则必须包含传输的值
  4. 如果 master 的 table 包含 value 但 transfer 没有,则必须显示 master 的 value。

我尝试了联合、加入等,但没有任何帮助我知道我在某处做错了什么,但我无法确定请帮助我。

我使用了以下查询,

select purchase_master.branch_id, sum(purchase_billvalue) as billvalue, sum(tra_value) as travalue 

from purchase_master 
join purchase_transfer on purchase_master.branch_id=purchase_transfer.branch_id 
where purchase_mindate=CURDATE() and tra_gtr_date=CURDATE() 
group by branch_id

仅当两个表包含当前日期时我才会获得值,但如果一个表有而另一个表没有,我不会获得任何值

我附上了表格的屏幕截图。

  1. 主表转移表 主表

  2. 转移表

我尝试了以下查询,但结果为空,

select pm.branch_id,pm.purchase_billvalue, pt.tra_value from purchase_master as pm
left outer join purchase_transfer as pt on pm.branch_id=pt.branch_id
where pm.purchase_mindate=CURDATE() and pt.tra_gtr_date=CURDATE()
union
select pm.branch_id,pm.purchase_billvalue, pt.tra_value from purchase_master as pm
right outer join purchase_transfer as pt on pm.branch_id = pt.branch_id
where pm.purchase_mindate=CURDATE() and pt.tra_gtr_date=CURDATE()

我需要结果为 sum(billvalue) sum(travalue) group by branch_id,

  1. 如果两个表包含 currentdate 数据
  2. 如果任何一个包含 currentdate 数据
4

2 回答 2

3

因为这两个表每个多行branch_id,所以您需要首先GROUP BY branch_id- 在每个表中分别 - 然后模拟FULL JOIN,要么使用UNION ALL一个以上,要么GROUP BY使用两个子查询,一个使用外连接LEFT,一个使用RIGHT外连接。

第一种(GROUP BY分别,然后UNION ALLGROUP BY)方式:

SELECT branch_id, 
       SUM(purchase_billvalue) AS purchase_billvalue, 
       SUM(tra_value) AS tra_value
FROM
  ( SELECT branch_id, 
           SUM(purchase_billvalue) AS purchase_billvalue,
           NULL AS tra_value
    FROM purchase_master
    WHERE purchase_mindate = CURDATE()
    GROUP BY branch_id
  UNION ALL
    SELECT branch_id, 
           NULL, 
           SUM(tra_value)
    FROM purchase_transfer  
    WHERE tra_gtr_date = CURDATE()
    GROUP BY branch_id
) AS u
GROUP BY branch_id ;

第三种方法 - 这可能是最有效的方法(但要进行测试!)在@peterm 的答案中提供。首先执行 a UNION(not UNION ALL) 以查找branch_id与两个表不同的所有内容,然后对LEFTGROUP BY branch_id单独执行 a 的派生表执行 2 次连接。

于 2013-09-08T08:43:39.333 回答
2

你可以做这样的事情

SELECT i.branch_id, 
       m.purchase_billvalue billvalue, 
       t.tra_travalue       travalue
  FROM
(
    SELECT branch_id
      FROM master
     WHERE purchase_mindate = CURDATE()
     UNION
    SELECT branch_id
      FROM transfer  
     WHERE tra_gtr_date = CURDATE()
) i LEFT JOIN 
(
  SELECT branch_id, SUM(purchase_billvalue) purchase_billvalue
    FROM master 
   WHERE purchase_mindate = CURDATE()
   GROUP BY branch_id
) m
    ON i.branch_id = m.branch_id LEFT JOIN 
(
  SELECT branch_id, SUM(tra_travalue) tra_travalue
    FROM transfer  
   WHERE tra_gtr_date = CURDATE()
   GROUP BY branch_id
) t
    ON i.branch_id = t.branch_id

示例输出(基于您的屏幕截图并假设所有显示行的两个表中的日期值都相等):

| BRANCH_ID | 比尔价值 | 旅游 |
|-----------|------------|----------|
| 2 | 72580.61 | 119947 |
| 3 | (空) | 9940 |

这是SQLFiddle演示

于 2013-09-08T07:28:07.180 回答