mysql两表汇总后再得到两表的交集和差集,请问怎么实现?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql两表汇总后再得到两表的交集和差集,请问怎么实现?相关的知识,希望对你有一定的参考价值。

如表A:
区域 省份 城市 编码 销量
华北 辽宁 沈阳 20020202 2
华东 山东 青岛 18020133 3
华北 北京 北京 7193 7
华北 北京 北京 8358 5
华北 北京 北京 9773 8
华东 山东 青岛 18020133 5

表B:
区域 省份 城市 编码 销量
华北 辽宁 沈阳 20020202 5
华东 山东 青岛 18020133 6
华北 北京 北京 7193 2
华东 甘肃 兰州 7364 3
华东 湖北 武汉 7512 7
华东 湖北 武汉 7512 2
华东 江苏 常州 7582 5
华东 江苏 淮安 7670 7

怎么得到如下表C:
区域 省份 城市 编码 表A销量 表B销量
华北 辽宁 沈阳 20020202 2 5
华东 山东 青岛 18020133 8 6
华北 北京 北京 7193 7 2
华北 北京 北京 8358 5
华北 北京 北京 9773 8
华东 山东 青岛 18020133 5
华东 甘肃 兰州 7364 3
华东 湖北 武汉 7512 9
华东 江苏 常州 7582 5
华东 江苏 淮安 7670 7
其中表C的结果是以编码汇总后的表A的编码在表B中没有的,表B中的编码在表A中没有的,编码在表A和表B中都有的数据

CREATE TABLE A (
`C1` VARCHAR(10),
`C2` VARCHAR(10),
`C3` VARCHAR(10),
`C4` VARCHAR(10),
`C5` INT
);

INSERT INTO A
SELECT '华北', '辽宁', '沈阳', '20020202', 2 UNION ALL
SELECT '华东', '山东', '青岛', '18020133', 3 UNION ALL
SELECT '华北', '北京', '北京', '7193', 7 UNION ALL
SELECT '华北', '北京', '北京', '8358', 5 UNION ALL
SELECT '华北', '北京', '北京', '9773', 8 UNION ALL
SELECT '华东', '山东', '青岛', '18020133', 5 ;

CREATE TABLE B (
`C1` VARCHAR(10),
`C2` VARCHAR(10),
`C3` VARCHAR(10),
`C4` VARCHAR(10),
`C5` INT
);
INSERT INTO B
SELECT '华北', '辽宁', '沈阳', '20020202', 5 UNION ALL
SELECT '华东', '山东', '青岛', '18020133', 6 UNION ALL
SELECT '华北', '北京', '北京', '7193', 2 UNION ALL
SELECT '华东', '甘肃', '兰州', '7364', 3 UNION ALL
SELECT '华东', '湖北', '武汉', '7512', 7 UNION ALL
SELECT '华东', '湖北', '武汉', '7512', 2 UNION ALL
SELECT '华东', '江苏', '常州', '7582', 5 UNION ALL
SELECT '华东', '江苏', '淮安', '7670', 7;

SELECT
IFNULL(A.`C1`, B.`C1`) AS `区域`,
IFNULL(A.`C2`, B.`C2`) AS `省份`,
IFNULL(A.`C3`, B.`C3`) AS `城市`,
IFNULL(A.`C4`, B.`C4`) AS `编码`,
SUM(A.`C5`) AS `表A销量`,
SUM(B.`C5`) AS `表B销量`
FROM
A LEFT JOIN B
ON (
A.`C1` = B.`C1` AND
A.`C2` = B.`C2` AND
A.`C3` = B.`C3` AND
A.`C4` = B.`C4`
)
GROUP BY
IFNULL(A.`C1`, B.`C1`),
IFNULL(A.`C2`, B.`C2`),
IFNULL(A.`C3`, B.`C3`),
IFNULL(A.`C4`, B.`C4`)
UNION
SELECT
IFNULL(A.`C1`, B.`C1`) AS `区域`,
IFNULL(A.`C2`, B.`C2`) AS `省份`,
IFNULL(A.`C3`, B.`C3`) AS `城市`,
IFNULL(A.`C4`, B.`C4`) AS `编码`,
SUM(A.`C5`) AS `表A销量`,
SUM(B.`C5`) AS `表B销量`
FROM
A RIGHT JOIN B
ON (
A.`C1` = B.`C1` AND
A.`C2` = B.`C2` AND
A.`C3` = B.`C3` AND
A.`C4` = B.`C4`
)
GROUP BY
IFNULL(A.`C1`, B.`C1`),
IFNULL(A.`C2`, B.`C2`),
IFNULL(A.`C3`, B.`C3`),
IFNULL(A.`C4`, B.`C4`);

+------+------+------+----------+---------+---------+
| 区域 | 省份 | 城市 | 编码 | 表A销量 | 表B销量 |
+------+------+------+----------+---------+---------+
| 华北 | 辽宁 | 沈阳 | 20020202 | 2 | 5 |
| 华北 | 北京 | 北京 | 7193 | 7 | 2 |
| 华北 | 北京 | 北京 | 8358 | 5 | NULL |
| 华北 | 北京 | 北京 | 9773 | 8 | NULL |
| 华东 | 山东 | 青岛 | 18020133 | 8 | 12 |
| 华东 | 甘肃 | 兰州 | 7364 | NULL | 3 |
| 华东 | 湖北 | 武汉 | 7512 | NULL | 9 |
| 华东 | 江苏 | 常州 | 7582 | NULL | 5 |
| 华东 | 江苏 | 淮安 | 7670 | NULL | 7 |
+------+------+------+----------+---------+---------+
9 rows in set (0.00 sec)追问

为什么 华东 | 山东 | 青岛 | 18020133 | 8 | 12 |这条中的表B不是而是12
执行的结果存在问题,首先表A有二条编码18020133 相同的,表B只有一条编码18020133 的记录,那么执行的结果就成了表A二条之和,表B一条的2倍了,反之是一样的。所以上面的语句得到的结果是错误的。

追答

恩,我原先的逻辑,是 先 关联,后合计, 现在看来有些问题. 需要修改一下:
修改为 先合计, 后 关联.

SELECT
IFNULL(A.`C1`, B.`C1`) AS `区域`,
IFNULL(A.`C2`, B.`C2`) AS `省份`,
IFNULL(A.`C3`, B.`C3`) AS `城市`,
IFNULL(A.`C4`, B.`C4`) AS `编码`,
IFNULL(A.`C5`, 0) AS `表A销量`,
IFNULL(B.`C5`, 0) AS `表B销量`
FROM
(SELECT C1, C2, C3, C4, SUM(C5) AS C5 FROM A GROUP BY C1, C2, C3, C4) A
LEFT JOIN (SELECT C1, C2, C3, C4, SUM(C5) AS C5 FROM B GROUP BY C1, C2, C3, C4) B
ON (
A.`C1` = B.`C1` AND
A.`C2` = B.`C2` AND
A.`C3` = B.`C3` AND
A.`C4` = B.`C4`
)
UNION
SELECT
IFNULL(A.`C1`, B.`C1`) AS `区域`,
IFNULL(A.`C2`, B.`C2`) AS `省份`,
IFNULL(A.`C3`, B.`C3`) AS `城市`,
IFNULL(A.`C4`, B.`C4`) AS `编码`,
IFNULL(A.`C5`, 0) AS `表A销量`,
IFNULL(B.`C5`, 0) AS `表B销量`
FROM
(SELECT C1, C2, C3, C4, SUM(C5) AS C5 FROM A GROUP BY C1, C2, C3, C4) A
RIGHT JOIN (SELECT C1, C2, C3, C4, SUM(C5) AS C5 FROM B GROUP BY C1, C2, C3, C4) B
ON (
A.`C1` = B.`C1` AND
A.`C2` = B.`C2` AND
A.`C3` = B.`C3` AND
A.`C4` = B.`C4`
);

+------+------+------+----------+---------+---------+
| 区域 | 省份 | 城市 | 编码 | 表A销量 | 表B销量 |
+------+------+------+----------+---------+---------+
| 华北 | 辽宁 | 沈阳 | 20020202 | 2 | 5 |
| 华北 | 北京 | 北京 | 7193 | 7 | 2 |
| 华北 | 北京 | 北京 | 8358 | 5 | 0 |
| 华北 | 北京 | 北京 | 9773 | 8 | 0 |
| 华东 | 山东 | 青岛 | 18020133 | 8 | 6 |
| 华东 | 甘肃 | 兰州 | 7364 | 0 | 3 |
| 华东 | 湖北 | 武汉 | 7512 | 0 | 9 |
| 华东 | 江苏 | 常州 | 7582 | 0 | 5 |
| 华东 | 江苏 | 淮安 | 7670 | 0 | 7 |
+------+------+------+----------+---------+---------+
9 rows in set (0.00 sec)

追问

还有比如:
表A
字段a
蓝JV255
S3250
OLD
钢T305
金T305
金T205
金JV255
金JV205
红Z909

表B
字段b
JA205
HB120

请问如何让字段a=字段b ,因为字段a中存在汉字。我写成select * from a,b where a.a=b.b or substring(a.a,2)=b.b,但如果字段a中有多个汉字就行不通了

追答

select * from a,b where a.a LIKE CONCAT ( '%' , b.b )
看看行不行?
这个我没测试.

参考技术A 你是要查前十个查询结果中相同的那些记录,而不求前十个相同记录吧,因为这是有差别的,按照你的语句,应该是求前者,即先求出A的前十条数据,B的前十条数据,再求它们的交集。

既然是求交集,那么这两个表的关系模式应该是相同的了,

select a.* from
(select * from table order by table.a desc limit 10) as a, (select * from table order by table.b desc limit 10) as b
where a.primary_key = b.primary_key --先将两个结果作为两张临时表,然后通过主键 primary_key来获取交集(交集肯定就是主键相等的了,因为关系模式相同)

mysql两表关联排序索引问题

两个表 a:id name create_date b_id 有30万数据
b: id name 有200数据
select a.id,a.b_id,a.name from a join b where a.b_id=b.id order by
1): a.create_date desc limit 0,30
2): b.name desc limit 0,30
如果在a表的create_date,b_id上建立索引第一种排序很快,只是单独建立create_date,或者b_id就用不到索引
第二种情况下a表只有b_id索引时很快?
请问怎么保证两种排序都快速

参考技术A Mysql中,一条SQL只能使用一个索引,所以 你在id列建立索引就可以了

以上是关于mysql两表汇总后再得到两表的交集和差集,请问怎么实现?的主要内容,如果未能解决你的问题,请参考以下文章

PHPEXCEL汇总两表的数据并加工

mysql 选择在一个table不在另一个table的数据

mysql两表关联排序索引问题

MySQL两表相同字段合并、更新,JAVA实现

MapReduce实现两表的Join--原理及python和java代码实现

MapReduce实现两表的Join--原理及python和java代码实现