MySQL加入vs联盟

时间:2017-11-02 00:49:45

标签: mysql sql join union

我有一个表message,其中列id(主键),parent_id(自我的外键),owner_id(创建者用户ID)和message(实际消息)。

我现在正在尝试检索由特定owner_id拥有的所有列,或者parent_id指向由特定owner_id拥有的另一条记录的所有列

我成功地做到了这一点:

select * from message m1
left join message m2 on m1.id = m2.parent_id
where m1.owner_id = 1;

但是,我得到了结果(右侧添加了m2列):

id  parent_id   owner_id    message         id      parent_id   owner_id    message
------------------------------------------------------------------------------------------
1   NULL        1           First message   3       1           2           Third message
1   NULL        1           First message   4       1           2           Fourth message
2   NULL        1           Second message  NULL    NULL        NULL        NULL

...当我想要这样的时候(所有唯一匹配列的简单列表,顺序并不重要):

id  parent_id   owner_id    message
------------------------------------------
1   NULL        1           First message
3   1           2           Third message
4   1           2           Fourth message
2   NULL        1           Second message

我意识到我可以使用union执行此操作,但我无法看到任何设计联合查询的方法,而不会使其效率极低。

你会如何解决这个问题?

感谢。

修改

这是我与之合作的表格:

create table message (
   id int(11) unsigned auto_increment primary key,
   parent_id int(11) unsigned default null,
   owner_id int(11) unsigned not null,
   message varchar(255) default null,

   index (parent_id),

   foreign key (parent_id) references message(id) on update cascade on delete cascade
) engine=innodb default charset=utf8;

3 个答案:

答案 0 :(得分:1)

左连接和要求的字面翻译都可以。

select m.* from message m 
left join message p on m.parent_id=p.id
where m.owner_id=1 or p.owner_id=1
order by m.id

上述SQL选择所有者ID为1或其父所有者ID为1的邮件。

SQLFiddle Example

答案 1 :(得分:0)

如果我理解正确,您需要父级或所有者为1的任何消息。然后,您希望按层次顺序排序。因为您只需要一个ID,我认为这样做符合您的要求:

select m.*
from message m
where 1 in (m.id, m.parent_id)
order by coalesce(m.parent_id, m.id), id;

答案 2 :(得分:0)

您可以使用union进行以下查询:

select id from message where owner_id="USER" --all the records for which the owner is directly "USER"
union all -- to remove duplicates generated by the union if any
select m1.id from message m1, message m2 where m1.parent_id=m2.parent_id and m1.id != m2.id and m2.owner_id="USER"
-- all the records from m2 that share the same parent_id as m1 (but that are not the same id to avoid taking the m1 record itself)
-- for which m2.owner is the specified one
祝你好运!干杯