在 mysql 中不使用连接合并两个表?
Merging two tables without using join in mysql?
我尝试合并来自两个不同 tables.The 的值,但没有成功,第一个显示如我所愿,但第二个每次只显示第一行。
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;
这是我得到的输出。
These is my selected_items table.
这是我的stock_list.
我的两个查询都是单独工作的,只有当我尝试 运行 它们在一起时我才能得到正确的输出它给第二个问题 query.Can 有人指出我的错误或告诉我更好的方法来做到这一点。
这就是我的最终 objective 是
您可以使用 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;
我不确定您想要的输出如何与您提供的查询相对应。但这应该按日期聚合和合并两个表中的数据,以便您可以完成查询。
如果某些日期可能不存在于两个表中,您可以使用 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
第一个问题是您在子查询 B
中按日期分组,但您没有 select 它,因此您的结果集可能类似于:
weightSum barcodeCount
---------------------------
26 8
9 14
4 7
这是 3 个日期的结果,但您不知道哪一行指的是哪个日期。
你的下一个问题是你正在使用交叉连接,因为你的两个查询之间没有 link,这意味着如果你的第一个查询 returns:
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 标准的细则、按子句分组和函数依赖,让我们将其简化为 MySQL 允许这样做,但除非您了解限制(这在 this answer 中对此有更详细的介绍),否则您不应该这样做。 select 中不在 group by 子句中的任何内容都应该在聚合中。
因此,由于 MySQL 的 GROUP BY 扩展 select 对所有内容进行分组并仅按日期分组,您实际上是说每个日期取 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;
我尝试合并来自两个不同 tables.The 的值,但没有成功,第一个显示如我所愿,但第二个每次只显示第一行。
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;
这是我得到的输出。
These is my selected_items table.
这是我的stock_list.
我的两个查询都是单独工作的,只有当我尝试 运行 它们在一起时我才能得到正确的输出它给第二个问题 query.Can 有人指出我的错误或告诉我更好的方法来做到这一点。
这就是我的最终 objective 是
您可以使用 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;
我不确定您想要的输出如何与您提供的查询相对应。但这应该按日期聚合和合并两个表中的数据,以便您可以完成查询。
如果某些日期可能不存在于两个表中,您可以使用 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
第一个问题是您在子查询 B
中按日期分组,但您没有 select 它,因此您的结果集可能类似于:
weightSum barcodeCount
---------------------------
26 8
9 14
4 7
这是 3 个日期的结果,但您不知道哪一行指的是哪个日期。
你的下一个问题是你正在使用交叉连接,因为你的两个查询之间没有 link,这意味着如果你的第一个查询 returns:
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 标准的细则、按子句分组和函数依赖,让我们将其简化为 MySQL 允许这样做,但除非您了解限制(这在 this answer 中对此有更详细的介绍),否则您不应该这样做。 select 中不在 group by 子句中的任何内容都应该在聚合中。
因此,由于 MySQL 的 GROUP BY 扩展 select 对所有内容进行分组并仅按日期分组,您实际上是说每个日期取 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;