FreeOZ论坛

标题: 多对一的JOIN怎么写呢? [打印本页]

作者: xblues    时间: 14-7-2009 01:15
提示: 作者被禁止或删除, 无法发言 标题: 多对一的JOIN怎么写呢?
表A 我有一个地址表,包含了具体地址和邮政编码,但是没有省份。
表B 另外一个表是邮政编码和省份的对应列表。

我想根据表B的对应关系,自动标出表A的每一行的省份,怎么写呢?
简单的

SELECT × FROM 表A LEFT JOIN 表B ON 表A.邮编 = 表B.邮编

好像不行,得到的结果集是A表的记录数的好几倍,好多重复记录
作者: NEWGAY    时间: 14-7-2009 01:23
标题: 回复 #1 xblues 的帖子
我记得select 后面好像有个关键字是distinction 可以过滤掉重复的
作者: ubuntuhk    时间: 14-7-2009 02:36
我用傻办法:
  1. SELECT a.address, a.zip, b.prov FROM table_A AS a, table_B AS b WHERE a.zip=b.zip;
复制代码

作者: xblues    时间: 14-7-2009 08:36
提示: 作者被禁止或删除, 无法发言 标题: 回复 #2 NEWGAY 的帖子
差不多,我看看,呵呵,忘记了。
作者: xblues    时间: 14-7-2009 08:37
提示: 作者被禁止或删除, 无法发言 标题: 回复 #3 ubuntuhk 的帖子
你这个和我上面的那个是一样的
WHERE 和 INNER JOIN,以及JOIN 都属于 INNER JOIN
作者: 周星星1832    时间: 14-7-2009 10:16
???一个邮编对应一个省份,咋会有重复记录???
作者: 周星星1832    时间: 14-7-2009 10:19
你的SQL是正确的
作者: 清风不写字    时间: 14-7-2009 10:56
除非数据有问题,不应该有重复的。
作者: coredump    时间: 14-7-2009 11:09
如果你写的没错(没把Join的次序搞反)的话,应该是表B有问题,比如邮编有重复等。
作者: stgeorge    时间: 14-7-2009 12:47
晕,你用的是left join. 自然会有重复的。但应该有null.
可以去掉left.
作者: 周星星1832    时间: 14-7-2009 12:52
原帖由 stgeorge 于 14-7-2009 11:47 发表
晕,你用的是left join. 自然会有重复的。但应该有null.
可以去掉left.

就是用JOIN也可能有重复如果B表有问题
作者: glite    时间: 14-7-2009 12:53
select * from table_a A left join (select distinct zip,area from table_b) B on A.zip=B.zip


应该还有更好的写法吧
作者: 周星星1832    时间: 14-7-2009 13:00
如果B表真的有问题,用JOIN 然后加个DISTINCT就行了
作者: coredump    时间: 14-7-2009 13:05
原帖由 stgeorge 于 14-7-2009 11:47 发表
晕,你用的是left join. 自然会有重复的。但应该有null.
可以去掉left.


去掉left是不对的,LZ的前提是需要保留所有A表的数据,没有left了且B表不完整的话,查询出来的结果可能会导致某些A表记录丢失
作者: NEWGAY    时间: 14-7-2009 22:51
这很正常。比如 澳洲的邮编 2144 是auburn nsw
2100是sydeny nsw,一个省有很多邮编
表是没有问题的。
作者: coredump    时间: 14-7-2009 22:57
原帖由 NEWGAY 于 14-7-2009 21:51 发表
这很正常。比如 澳洲的邮编 2144 是auburn nsw
2100是sydeny nsw,一个省有很多邮编
表是没有问题的。


没看懂题目,罚抄写100遍。
作者: formatc    时间: 14-7-2009 23:00
讨论技术的男人可真有魅力………………
作者: xblues    时间: 15-7-2009 00:13
提示: 作者被禁止或删除, 无法发言 标题: 回复 #16 coredump 的帖子
表没问题的,就是NEWGAY说的那样,多个邮编对应一个省份。
这个目前的办法只有像NEWGAY说的那样用

(这个记录全) SELECT DISTINCT 邮编 FROM 主表 LEFT JOIN 邮编表 ON 邮编相等

(这个会少几条)SELECT DISTINCT 邮编 FROM 主表,邮编表 WHERE 邮编相等

这样虽然费时间,但是也是目前唯一的办法了。
因为邮编表是多对一的,主表和邮编表MAPPING肯定会产生重复记录。
作者: coredump    时间: 15-7-2009 00:22
标题: 回复 #18 xblues 的帖子
我靠,那是你的表述有问题。

你的B表,邮编是不是主键?
作者: gdzack    时间: 15-7-2009 00:52
我同意啊,的确是LZ表述的问题。
作者: 周星星1832    时间: 15-7-2009 12:43

作者: 清风不写字    时间: 15-7-2009 14:00

作者: someonehappy    时间: 15-7-2009 14:17
是表结构设计问题
作者: sonybp    时间: 16-7-2009 01:13
明显B表的邮政编码字段不是唯一的。先把B表清理一遍吧。
作者: xincheng    时间: 23-9-2009 16:06
楼上各位说的很明白了,其实很多问题都出在结构设计上,检查B表邮编字段是否包含空值和重复数据,净化数据后,改变其为not null,如果可以,建立PK,否则也要建立UK,这样连接效率也会提升。
作者: earthengine    时间: 23-9-2009 17:34
如果不用DISTINCT,可以用GROUP BY,但因为没有聚集字段,所有SELECT的字段都必须出现在GROUP BY子句里。

比如

SELECT 表A.address, 表A.zip, 表B.prov FROM 表A LEFT JOIN 表B ON 表A.邮编 = 表B.邮编
GROUP BY 表A.address, 表A.zip, 表B.prov

另外,为了确定问题出在B表处,可以专门针对B表做DISTINCT

SELECT 表A.address, 表A.zip, B.prov FROM 表A LEFT JOIN (SELECT DISTINCT zip,prov FROM 表B) B  ON 表A.邮编 = B.邮编
或者 GROUP BY
SELECT 表A.address, 表A.zip, B.prov FROM 表A LEFT JOIN (SELECT zip,prov FROM 表B GROUP BY zip,prov) B  ON 表A.邮编 = B.邮编




欢迎光临 FreeOZ论坛 (https://www.freeoz.org/ibbs/) Powered by Discuz! X3.2