找回密码
 FreeOZ用户注册
查看: 2275|回复: 25

[数据库] 多对一的JOIN怎么写呢?

[复制链接]
发表于 14-7-2009 01:15:26 | 显示全部楼层 |阅读模式
提示: 作者被禁止或删除, 无法发言

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?FreeOZ用户注册

x
表A 我有一个地址表,包含了具体地址和邮政编码,但是没有省份。
表B 另外一个表是邮政编码和省份的对应列表。

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

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

好像不行,得到的结果集是A表的记录数的好几倍,好多重复记录
回复  

使用道具 举报

发表于 14-7-2009 01:23:20 | 显示全部楼层

回复 #1 xblues 的帖子

我记得select 后面好像有个关键字是distinction 可以过滤掉重复的
回复  

使用道具 举报

发表于 14-7-2009 02:36:13 | 显示全部楼层
我用傻办法:
  1. SELECT a.address, a.zip, b.prov FROM table_A AS a, table_B AS b WHERE a.zip=b.zip;
复制代码
回复  

使用道具 举报

 楼主| 发表于 14-7-2009 08:36:04 | 显示全部楼层

回复 #2 NEWGAY 的帖子

提示: 作者被禁止或删除, 无法发言
差不多,我看看,呵呵,忘记了。
回复  

使用道具 举报

 楼主| 发表于 14-7-2009 08:37:08 | 显示全部楼层

回复 #3 ubuntuhk 的帖子

提示: 作者被禁止或删除, 无法发言
你这个和我上面的那个是一样的
WHERE 和 INNER JOIN,以及JOIN 都属于 INNER JOIN
回复  

使用道具 举报

发表于 14-7-2009 10:16:22 | 显示全部楼层
???一个邮编对应一个省份,咋会有重复记录???
回复  

使用道具 举报

发表于 14-7-2009 10:19:36 | 显示全部楼层
你的SQL是正确的
回复  

使用道具 举报

发表于 14-7-2009 10:56:03 | 显示全部楼层
除非数据有问题,不应该有重复的。
回复  

使用道具 举报

发表于 14-7-2009 11:09:52 | 显示全部楼层
如果你写的没错(没把Join的次序搞反)的话,应该是表B有问题,比如邮编有重复等。
回复  

使用道具 举报

发表于 14-7-2009 12:47:18 | 显示全部楼层
晕,你用的是left join. 自然会有重复的。但应该有null.
可以去掉left.
回复  

使用道具 举报

发表于 14-7-2009 12:52:46 | 显示全部楼层
回复  

使用道具 举报

发表于 14-7-2009 12:53:56 | 显示全部楼层
select * from table_a A left join (select distinct zip,area from table_b) B on A.zip=B.zip


应该还有更好的写法吧
回复  

使用道具 举报

发表于 14-7-2009 13:00:09 | 显示全部楼层
如果B表真的有问题,用JOIN 然后加个DISTINCT就行了
回复  

使用道具 举报

发表于 14-7-2009 13:05:26 | 显示全部楼层
原帖由 stgeorge 于 14-7-2009 11:47 发表
晕,你用的是left join. 自然会有重复的。但应该有null.
可以去掉left.


去掉left是不对的,LZ的前提是需要保留所有A表的数据,没有left了且B表不完整的话,查询出来的结果可能会导致某些A表记录丢失
回复  

使用道具 举报

发表于 14-7-2009 22:51:45 | 显示全部楼层
这很正常。比如 澳洲的邮编 2144 是auburn nsw
2100是sydeny nsw,一个省有很多邮编
表是没有问题的。

评分

参与人数 1威望 +1 收起 理由
coredump + 1 学习不认真

查看全部评分

回复  

使用道具 举报

发表于 14-7-2009 22:57:04 | 显示全部楼层
原帖由 NEWGAY 于 14-7-2009 21:51 发表
这很正常。比如 澳洲的邮编 2144 是auburn nsw
2100是sydeny nsw,一个省有很多邮编
表是没有问题的。


没看懂题目,罚抄写100遍。
回复  

使用道具 举报

发表于 14-7-2009 23:00:06 | 显示全部楼层
讨论技术的男人可真有魅力………………
回复  

使用道具 举报

 楼主| 发表于 15-7-2009 00:13:20 | 显示全部楼层

回复 #16 coredump 的帖子

提示: 作者被禁止或删除, 无法发言
表没问题的,就是NEWGAY说的那样,多个邮编对应一个省份。
这个目前的办法只有像NEWGAY说的那样用

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

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

这样虽然费时间,但是也是目前唯一的办法了。
因为邮编表是多对一的,主表和邮编表MAPPING肯定会产生重复记录。
回复  

使用道具 举报

发表于 15-7-2009 00:22:20 | 显示全部楼层

回复 #18 xblues 的帖子

我靠,那是你的表述有问题。

你的B表,邮编是不是主键?
回复  

使用道具 举报

发表于 15-7-2009 00:52:24 | 显示全部楼层
我同意啊,的确是LZ表述的问题。
回复  

使用道具 举报

发表于 15-7-2009 12:43:20 | 显示全部楼层
回复  

使用道具 举报

发表于 15-7-2009 14:00:32 | 显示全部楼层
回复  

使用道具 举报

发表于 15-7-2009 14:17:30 | 显示全部楼层
是表结构设计问题
回复  

使用道具 举报

发表于 16-7-2009 01:13:24 | 显示全部楼层
明显B表的邮政编码字段不是唯一的。先把B表清理一遍吧。
回复  

使用道具 举报

发表于 23-9-2009 16:06:13 | 显示全部楼层
楼上各位说的很明白了,其实很多问题都出在结构设计上,检查B表邮编字段是否包含空值和重复数据,净化数据后,改变其为not null,如果可以,建立PK,否则也要建立UK,这样连接效率也会提升。
回复  

使用道具 举报

发表于 23-9-2009 17:34:29 | 显示全部楼层
如果不用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.邮编

评分

参与人数 1威望 +49 收起 理由
xblues + 49 谢谢分享!

查看全部评分

回复  

使用道具 举报

您需要登录后才可以回帖 登录 | FreeOZ用户注册

本版积分规则

小黑屋|手机版|Archiver|FreeOZ论坛

GMT+11, 29-3-2024 17:59 , Processed in 0.075515 second(s), 45 queries , Gzip On, Redis On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表