我在尝试使用MySQL查询避免部分重复结果时出现问题。我承认我在MySQL方面真的很新,但我从SO的研究中学到了我在下面为你设计的模式绝对可以做得更好(用户表的linked_users列应该是一个单独的表)。但是,我现在无法改变它的设置方式。
我尝试返回分配给t2中每个项目的用户ID的用户名或链接到这些用户的用户的用户名。但是,查询为每个项返回两组名称。我认为这种情况正在发生,因为它正在搜索它们两次,并且我试图在SO上阅读关于从多个表中返回多个值的this tutorial,但我似乎无法将我的想法包围在JOINS和UNIONS等等。
我的问题是双重的:
感谢您的时间。
架构:
create table users (user_id int, user_name varchar (55), linked_users varchar (55));
insert into users( user_id, user_name, linked_users)values(1, 'user1', '2,154,4,45');
insert into users( user_id, user_name, linked_users)values(2, 'user2', '13,1,200');
create table t2 (t2_id int, user_id int);
insert into t2( t2_id, user_id)values(1, 2);
insert into t2( t2_id, user_id)values(2, 1);
insert into t2( t2_id, user_id)values(3, 1);
insert into t2( t2_id, user_id)values(4, 2);
insert into t2( t2_id, user_id)values(5, 3);
查询:
SELECT t.*, u.user_name
FROM t2 t, users u
WHERE t.user_id = u.user_id
OR find_in_set(t.user_id, u.linked_users) > 0
答案 0 :(得分:1)
您在同一张表中有多对多的关系。一个用户可以具有许多链接用户,并且用户可以是多于一个用户的链接用户。要表示您需要一个可以调用linked_users的附加表,该表由两列定义:
user_id int foreign key to user_id in users table
linked_user_id int foreign key to user_id in users table
此表的主键应该是user_id和linked_user_id
现在,让我们假设你有1到10个用户,其中1个有5,6,8个作为链接用户,3个有1个,6个,10个作为链接用户。你应该插入
1, 5
1, 6
1, 8
3, 1
3, 6
3, 10
在linked_users中。您的查询变为:
select u1.*, u2.*
from users u1 inner join linked_users lu on u1.user_id = lu.user_id
inner join users u2 on lu.linked_user_id = u2.user_id
如果你必须坚持你的设计
select u1.*, u2.*
from users u1 inner join users u2 on
find_in_set(u2.user_id, u1.linked_users) > 0
答案 1 :(得分:1)
您绝对应该更改表格的结构。正确的结构将使用两个表,一个用于实体(“用户”),另一个用于它们之间的关系:
create table users (
user_id int not null primary key auto_increment,
user_name varchar(55)
);
create table userlinks (
user_id int not null references users(user_id),
linked_user_id int not null references users(user_id)
);
创建表t2( t2_id int, user_id int not null引用用户(user_id) );
你的结构有几个明显的缺陷:
使用此结构,您可以使用distinct
获取给定“t”值的用户列表,而不使用exists
,而不使用select u.user_id
from users u cross join
(select user_id from t2 where t2.tid = 1) t
where u.user_id = t.user_id or
exists (select 1
from ul
where ul.user_id = t.user_id and
u.user_id = ul.linked_user_id
);
:
t2
该查询说:“获取用户ID与user_id
中相应ID相匹配的所有用户,或者该用户与t2
中的select u.user_id
from users u cross join
(select user_id from t2 where t2.tid = 1) t
where u.user_id = t.user_id or
find_in_set(u.user_id,
(select u.linked_users from users u2 where u2.user_id = t.user_id)
) > 0;
相关联。”
作为一个注释,您也可以通过以下方式对您的结构执行此操作:
<style type="text/css">
* {
font-family: Lucida Sans Unicode, Lucida Grande, sans-serif;
}
body {
background-color: white ;
color: #543864 ;
z-index: -10;
clear: both;
}
#topmenu {
float: left;
padding-top: 50px;
position: relative;
}
#topmenu ul {
list-style:none;
}
#topmenu li {
float:left;
padding: 5px 30px 0px 20px;
margin-right: 20px;
border-right: 1px solid #292E37;
text-decoration: underline;
}
a:hover {
font-size: 20px;
}
a:link {
color: #292E37;
}
#name {
margin-bottom: 5px;
color: #543864;
display:inline-block;
}
#topcontainer {
width: 100%;
height: 60px;
margin-bottom: 15%;
font-family: Lucida Grande;
margin-right: 50px;
border-radius: 25px;
float: left;
position: relative;
text-align: center;
padding-bottom: 10%;
}
#footer {
background-color:#B9B7C4;
height: 11%;
width: 100%;
z-index: 1;
position:absolute;
margin-top: 10%;
margin-bottom: 10%;
}
#wrapper {
margin-right: auto;
margin-left: auto;
width: 960px;
}
#Header {
float:left;
padding-left: 75px;
}
.circlefooter {
width: 50px;
height: 50px;
float: left;
margin: 25px 25px 0 175px;
}
.circlefooter p {
padding-left: 75px;
width: 150px;
font-size: 12px;
}
.circlefooter img {
height: 50px;
float: left;
}
.circlefooter a:hover {
font-size: 12px;
}
</style>
答案 2 :(得分:0)
感谢Gordon和Tarik的回复。我尝试了你在我的小提琴中提供的代码,但是无法提取t2信息,所以在弄乱了它之后我发现这个查询解决了我遇到的问题:
SELECT t2.*, u.user_name
FROM users u, t2 t
WHERE t.user_id = u.user_id
AND (t.user_id = '$user_id'
OR t.user_id IN
(SELECT u2.user_id
FROM users u2
WHERE find_in_set('$user_id', u2.linked_users)
)
)
同样,我知道这不是最好的方法,但由于我无法改变结构,这将有助于达到目的。