1:n mysql 5.1.41中的数据结构不会工作

时间:2010-12-05 21:23:10

标签: mysql

我正在使用mysql 5.1.41解决用户应该能够指定他所说的语言的问题。这根本不是问题,但确实存在问题 我想到了这样的结构:

CREATE TABLE `user2lang` (
  `id` int(11) NOT NULL auto_increment,
  `user` int(11) NOT NULL,
  `lang` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) 

和第二张表

CREATE TABLE `lang` (
  `id` int(11) NOT NULL auto_increment,
  `langname` varchar(50) NOT NULL,
  PRIMARY KEY  (`id`)
)

在表格中是一个包含语言的列表,例如

id : langname 
1  : eng
2  : ger
3  : lat

并且在表I中存储哪个用户确实说出了什么语言的id

id : user : lang
1  : 1 : 1 (eng)
2  : 1 : 3 (lat)
3  : 2 : 2 (ger)
4  : 2 : 1 (eng)

现在我想获取所有可用语言的列表,如果特殊用户(用户#2)能够说出来,则应标记。
显而易见的应该是左连接:

SELECT user2lang.lang,user2lang.user
FROM `user2lang` left join lang on
lang.id = user2lang.lang where
user2lang.user=2

我得到的只是用户#2所说的语言,而不是所有带有信息的语言,如果用户#2确实说的话。我正在寻找类似的东西:

lang : user 
1    : 2 
2    : 2 
3    : - or NUll or whatever 
4    : -

3 个答案:

答案 0 :(得分:1)

只需更改join子句就可以了:

SELECT lang.id ,user2lang.user
FROM `lang` left join `user2lang` on
lang.id = user2lang.lang AND user2lang.user=2

答案 1 :(得分:0)

左转连接,以便表lang位于左连接的左侧:

SELECT lang.id ,user2lang.user
FROM `lang` left join `user2lang` on
lang.id = user2lang.lang where
user2lang.user=2

修改

1 - 您需要确保您的预测从lang表中提取lang值,而不是user2lang。所以它应该是:SELECT lang.id, user2lang.user 不是 SELECT user2lang.lang, user2lang.user

2 - 如果要显示所有语言,则必须在where子句中包含OR user2lang.user is NULL。像这样:

SELECT lang.id, lang.langname, user2lang.user 
FROM lang left join user2lang 
  ON user2lang.lang=lang.id 
WHERE user2lang.user=2 or user2lang.user is null;

编辑(再次)

虽然上面的代码示例确实有用 - @iliyan,但实际上有正确的答案。限制user2lang.user=2应该进入ON子句。进行查询:

SELECT lang.id, lang.langname, user2lang.user 
FROM lang left join user2lang 
  ON user2lang.lang=lang.id AND user2lang.user=2;

这比我上面提到的is null位更好。

答案 2 :(得分:0)

我亲自改变你的设计,将你的user2lang表中不必要的代理主键放到以下设计中,以便更好地强制执行数据完整性(不包括RI):

drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key, -- unsigned pls
username varbinary(32) unique not null
)
engine=innodb;

drop table if exists languages;
create table languages
(
lang_id smallint unsigned not null auto_increment primary key, -- how many languages ?
name varchar(255) unique not null
)
engine=innodb;

drop table if exists user_languages;
create table user_languages
(
user_id int unsigned not null,
lang_id smallint unsigned not null,
primary key (user_id, lang_id) -- clustered composite PK super fast (innodb only)
)
engine=innodb;