子查询 - 记录不是有序的形式

时间:2015-02-24 10:34:28

标签: mysql sql subquery sql-order-by

我有三张桌子:

user: id, name
keyword: id, name
userkeyword: id, user_id, keyword_id

我想以下列方式执行查询:

  

显示关键字/ s与登录用户匹配的用户   关键字。按关键字匹配用户的最大数量顺序   应首先显示

例如:如果userA有4个匹配的关键字,userB有8个,userC有1个,userD有6个,那么结果应按顺序排列,

userB
userD
userA
userC

为此,我已完成此查询(假设登录用户的id为1):

select * 
from user 
where id IN (
    select user_id 
    from userkeywords 
    where keyword_id IN (
        select keyword_id 
        from userkeywords 
        where user_id=1) 
    group by user_id 
    order by count(keyword_id) desc) 
    AND id != 1

这里的结果很完美,但订单不正确。我已按以下方式合并了两个查询“

 select * 
 from user 
 where id IN (?) 
      AND id!=1

+

 select user_id
 from userkeywords 
 where keyword_id IN (
      select keyword_id 
      from userkeywords 
      where user_id=1) 
 group by user_id 
 order by count(keyword_id) desc

第二个查询以正确的顺序返回user_id但是当我合并两个查询时,订单被更改(错误)。

希望我已经足够详细地提及了我的查询。

3 个答案:

答案 0 :(得分:2)

子查询返回一个无序集,因此子查询中的order by仅对其limit子句有意义(如果有的话)。除MySQL之外的任何数据库都会给出纯装饰排序顺序的错误消息。

无法对仅存在于where子句中的列进行排序。你必须重写查询。一种选择是将in条件替换为joins

select  uk2.name
from    userkeywords uk1
join    userkeywords uk2
on      uk1.keyword_id = uk2.keyword_id
        and uk1.user_id <> uk2.user_id
join    user u2
on      u2.id = uk2.user_id
where   uk1.user_id = 1
group by
        uk2.name
order by
        count(*) desc

答案 1 :(得分:0)

这应该这样做。

select uk.user_id, u.name
from userkeywords uk
left join user u on u.id = uk.user_id
where uk.keyword_id IN ( 
    select keyword_id 
    from userkeywords 
    where user_id=1) 
group by uk.user_id 
order by count(uk.keyword_id) desc) AND uk.user_id != 1

此外,JOIN可提供更好的效果。

答案 2 :(得分:0)

我会使用内连接来选择正确的行:

SELECT *
FROM user
INNER JOIN (
   SELECT * FROM userkeyword 
   WHERE keyword_id IN (
       SELECT keyword_id 
       FROM userkeyword 
       WHERE user_id=1
   )
) uk 
ON user.id = uk.user_id 
GROUP BY u.id
ORDER BY count(*) DESC;