The first problem is that you are grouping by date in your subquery B
, but you don't select it, so your result set might be something like:
weightSum barcodeCount
---------------------------
26 8
9 14
4 7
This is the result for 3 dates, but you have no idea which date which row refers to.
Your next problem is that you are using a cross join, because there is no link between your two queries, this means if your first query returns:
Date qtySum weightSum
----------------------------------------
2016-01-20 1 1
2016-01-21 2 2
After you have done this cross join you end up:
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
So every row from A is matched with every row from B giving you 6 total rows.
Your third problem is that you then group by date, but don't perform any aggregates, without delving too much into the fine print of the SQL Standard, the group by clause, and functional dependency, lets simplify it to MySQL allows this, but you shouldn't do it unless you understand the limitations (This is covered in more detail on this in this answer). Anything in the select that is not in a group by clause should probably be within an aggregate.
So, due to MySQL's GROUP BY Extension by selecting everything and grouping only by date, what you are effectively saying is take 1 row per date, but you have no control over which row, it might be the first row from each group as displayed above, so the result you would get is:
Date qtySum a.weightSum b.weightSum barcodeCount
--------------------------------------------------------------------------
2016-01-20 1 1 26 8
2016-01-21 2 2 26 8
Which I think is why you are ending up with all the same values from the subquery B repeated.
So that covers what is wrong, now on to a solution, assuming there will be dates in stock_list
that don't exist in selected_items
, and vice versa you would need a full join, but since this is not supported in MySQL you would have to use UNION
, the simplest way would be:
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;
EDIT
I can't test this, nor am I sure of your exact logic, but you can use variables to calculate a running total in MySQL. This should give an idea of how to do it:
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;