合并两个表而不使用mysql中的join?

时间:2016-01-20 12:58:55

标签: mysql sql date join union

我尝试合并来自两个不同表的值是不成功的。第一个显示就像我想要的那样,但第二个每次只显示第一行。

Select * From (Select date as Date, Sum(qty) as qtySum, Sum(weight) 
as weightSum From stock_list Group by date) as A,
(Select Sum(weight) as weightSum,Count(barcode)
as barcodeCount From selected_items Group by date) as B Group by date;

这是我得到的输出。

enter image description here

  

这是我的selected_items表。

enter image description here

这是我的stock_list。enter image description here

我的查询都是单独工作的,只有当我尝试一起运行它才能获得正确的输出它会给第二个查询带来问题。任何人都可以指出我的错误或给我一个更好的方法来做到这一点。 这就是我的最终目标是enter image description here

3 个答案:

答案 0 :(得分:1)

第一个问题是您在子查询B中按日期分组,但是您没有选择它,因此您的结果集可能类似于:

weightSum       barcodeCount
---------------------------
26              8
9               14
4               7

这是3个日期的结果,但您不知道哪个日期指的是哪个行。

您的下一个问题是您正在使用交叉联接,因为您的两个查询之间没有链接,这意味着如果您的第一个查询返回:

Date            qtySum      weightSum
----------------------------------------
2016-01-20      1           1
2016-01-21      2           2

完成此交叉加入后,您最终:

Date            qtySum      a.weightSum     b.weightSum     barcodeCount
--------------------------------------------------------------------------
2016-01-20      1           1               26              8
2016-01-20      1           1               9               14
2016-01-20      1           1               4               7
2016-01-21      2           2               26              8
2016-01-21      2           2               9               14
2016-01-21      2           2               4               7

因此A中的每一行都与B中的每一行匹配,总共有6行。

你的第三个问题是,你按日期分组,但不执行任何聚合,没有深入研究SQL Standard的细则,group by子句和函数依赖,让我们简化它到MySQL允许这个,但你不应该这样做,除非你理解这些限制(这在this answer中有更详细的介绍)。 select中不在group by子句中的任何内容都应该在聚合中。

所以,由于MySQL的GROUP BY Extension通过选择所有内容并仅按日期分组,你实际上说的是每个日期占用1行,但是你无法控制哪一行,它可能是每个组的第一行如上所示,您得到的结果是:

Date            qtySum      a.weightSum     b.weightSum     barcodeCount
--------------------------------------------------------------------------
2016-01-20      1           1               26              8
2016-01-21      2           2               26              8

我认为这就是为什么你最终会重复使用子查询B中所有相同的值。

所以这涵盖了什么是错的,现在解决方案,假设stock_list中的日期在selected_items中不存在,反之亦然,你需要一个完整的联接,但是由于MySQL不支持,因此必须使用UNION,最简单的方法是:

SELECT  t.Date,
        SUM(t.StockQuantity) AS StockQuantity, 
        SUM(t.StockWeight) AS StockWeight, 
        SUM(t.SelectedWeight) AS SelectedWeight, 
        SUM(t.BarcodeCount) AS BarcodeCount
FROM    (   SELECT  date, 
                    SUM(qty) AS StockQuantity, 
                    SUM(weight) AS StockWeight, 
                    0 AS SelectedWeight, 
                    0 AS BarcodeCount
            FROM    stock_list
            GROUP BY Date
            UNION ALL
            SELECT  date, 
                    0 AS StockQuantity, 
                    0 AS StockWeight, 
                    SUM(weight) AS SelectedWeight, 
                    COUNT(BarCode) AS BarcodeCount
            FROM    selected_items
            GROUP BY Date
        ) AS t
GROUP BY t.Date;

修改

我无法对此进行测试,也不确定您的确切逻辑,但您可以使用variables to calculate a running total in MySQL。这应该让我们知道如何做到这一点:

SELECT  Date,
        StockQuantity,
        StockWeight,
        SelectedWeight,
        BarcodeCount,
        (@w := @w + StockWeight -  SelectedWeight) AS TotalWeight,
        (@q := @q + StockQuantity - BarcodeCount) AS TotalQuantity
FROM    (   SELECT  t.Date,
                    SUM(t.StockQuantity) AS StockQuantity, 
                    SUM(t.StockWeight) AS StockWeight, 
                    SUM(t.SelectedWeight) AS SelectedWeight, 
                    SUM(t.BarcodeCount) AS BarcodeCount
            FROM    (   SELECT  date, 
                                SUM(qty) AS StockQuantity, 
                                SUM(weight) AS StockWeight, 
                                0 AS SelectedWeight, 
                                0 AS BarcodeCount
                        FROM    stock_list
                        GROUP BY Date
                        UNION ALL
                        SELECT  date, 
                                0 AS StockQuantity, 
                                0 AS StockWeight, 
                                SUM(weight) AS SelectedWeight, 
                                COUNT(BarCode) AS BarcodeCount
                        FROM    selected_items
                        GROUP BY Date
                    ) AS t
            GROUP BY t.Date
        ) AS t
        CROSS JOIN (SELECT @w := 0, @q := 0) AS v
GROUP BY t.Date;

答案 1 :(得分:0)

您可以使用join。但是,如果两个表中的日期集不相同,那么您需要full outer join。但这在MySQL中不可用。代替:

select date, sum(qtySum), sum(weightsum1), sum(weightsum2), sum(barcodeCount)
from ((Select date as Date, Sum(qty) as qtySum, Sum(weight) as weightSum1,
              NULL as weightsum2, NULL as barcodeCount
        From stock_list
        Group by date
       ) union all
       (Select date, null, null, Sum(weight), Count(barcode) as barcodeCount 
        From selected_items
        Group by date
       )
      ) t
Group by date;

我不确定您所需的输出与您提供的查询的对应关系。但是这应该按日期汇总和组合来自两个表的数据,因此您可以最终确定查询。

答案 2 :(得分:0)

如果两个表中可能不存在某些日期,您可以使用FULL JOIN运算符来解决您的任务。

Select ISNULL(A.date, B.date) AS date,
       A.qtySum,
       A.weightSum,
       B.weightSum,
       B.barcodeCount
From 
    (Select date as Date, 
            Sum(qty) as qtySum, 
            Sum(weight) as weightSum 
     From stock_list 
     Group by date) as A
FULL JOIN
(Select date,
        Sum(weight) as weightSum,
        Count(barcode) as barcodeCount 
 From selected_items 
 Group by date) as B ON A.date = B.date