【问题标题】:Subquery - records are not in ordered form子查询 - 记录不是有序的
【发布时间】:2023-03-22 07:31:01
【问题描述】:

我有三张桌子:

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

我想通过以下方式执行查询:

显示关键字与登录用户匹配的用户 关键词。按关键字匹配用户的最大数量排序 应该首先显示

e.g : 如果 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,但是当我合并两个查询时,顺序发生了变化(错误)。

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

【问题讨论】:

  • @Strawberry:看起来我们的编辑有冲突,认为我的编辑更彻底,所以回滚了
  • 如果您愿意,请考虑遵循以下简单的两步操作: 1. 如果您还没有这样做(您还没有这样做),请提供适当的 DDL(和/或 sqlfiddle),以便我们可以更容易地复制问题。 2. 如果您还没有这样做(同样,您还没有这样做),请提供与步骤 1 中提供的信息相对应的所需结果集。

标签: mysql sql subquery sql-order-by


【解决方案1】:

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

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

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

【讨论】:

  • "MySQL 说:#1241 - 操作数应包含 1 列" - 我认为它位于 user_id , count(*)
  • 哎呀,是的,这是有道理的。我已经更新了答案。
  • 完美。!!但是有没有任何选项可以通过子查询实现这一点?
  • @NiravDangi,为什么需要子查询? (学校作业??
  • @jarlh 是的,请帮我完成我的学校作业。我期待您至少提供学校层面的帮助。使用 SCHOOL LEVEL 子查询等待您的回答。希望你能做得更好
【解决方案2】:

应该这样做。

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 提供更好的性能。

【讨论】:

  • 最后一行代码有点奇怪。剪切和粘贴错误?
  • 当我从移动应用程序输入时,我无法正确测试它,但 IMO 它可以工作。
  • 没什么大不了的,等有大屏幕的时候再看看吧。
【解决方案3】:

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

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;

【讨论】:

  • 此查询不会在其结果集中返回原始用户(用户1 而不是3 btw)吗?
  • 不需要在 GROUP BY 中列出更多列,因为你做了“选择 *”?
  • 我执行了查询,它产生了一个用户列表,按用户 1(或 3 或其他)的常用关键字数量排序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多