3

我有两张表说:用户和图书馆。图书馆包含以某种方式分类的书籍;用户也可以选择以某种方式对他的书进行分类。这两个表的结构(和样本数据)如下所示:

图书馆

bookid 位置
10 1
12 2
14 3
16 4

用户

userid bookid 位置
12669 12 1
12669 10 2

我想要一个查询来返回用户 12669 的所有书籍,按位置排序,即:


select bookid from user where userid = 12669 group by position

在它返回这些排序的书籍后,它应该返回图书馆中的其他 bookid(用户中不存在)。不应重复任何 bookid。这些场景的结果将如下所示:

12
10
14
16

换句话说:图书馆中的所有书籍都应该由这个查询返回,但是用户选择的书籍是根据 user.position 排序的,

我认为我可能需要某种连接语句。我试过:
从用户 u 中选择 bookid 右加入库 l on u.bookid = l.bookid where u.userid = 12669 group by u.position

但是,我得到一个语法错误。解决这个“问题”的最佳方法是什么?非常感谢。

4

4 回答 4

1

这应该可以解决问题:)

SELECT l.bookid
FROM library l
LEFT OUTER JOIN user u on u.bookid = l.bookid
WHERE u.userid = 12669
ORDER BY isnull(u.position, 99999), l.position
于 2012-05-15T14:44:00.270 回答
1

首先,您发布的查询在其投影中包含一个不属于所涉及的任何一个表的列名。

其次,您使用的是 GROUP BY,其中排序由 ORDER BY 执行。

第三点:正如@Romil 指出的那样,在 WHERE 子句中对 USER 表的引用会覆盖外连接,并有效地强制执行内连接。因此,您需要从 USER 表的内联视图中进行选择。

最后,要获得您想要的排序顺序,您需要首先对所有 USER.POSITION 进行绑定。此版本的查询使用 IFNULL 为没有连接 USER 记录的任何行分配一个极高的值。因此,它将按所有返回的 USER.POSITION 值排序,然后按 LIBRARY.POSITION 对所有剩余书籍进行排序。

select l.bookid 
from ( select * from user
        where userid = 12669 ) u
   right join library l 
     on (u.bookid = l.bookid) 
order by ifnull(u.position, 999999999) , l.position

注意:如果您正在索引Babel 图书馆,那么可能有足够的书架来支持超过 999999999 个位置,只需提高该替代值即可。


“这对我不起作用。它没有按照我想要的安排返回书名。”

坦率地说,我觉得这很令人惊讶。这是一个 SqlFiddle,它肯定会按照您指定的顺序返回您的示例数据。所以我重复我之前的问题:您发布的表格描述是否与您的实际表格完全匹配?

于 2012-05-15T14:58:03.730 回答
0

感谢 APC、Romil 和 aF。我终于想出了一个不使用连接的解决方案。这对我有用:

(
选择书号
来自用户
其中用户 ID = 12669
按位置排序
)
联合(
选择书号
来自库
)

第一个查询从用户中选择已排序的bookid,然后联合语句从库中选择所有其他书籍并将其添加到结果集中。这后一组的安排并不重要。

于 2012-05-15T22:42:38.983 回答
0
SELECT library.bookid bookid 
FROM   library 
       LEFT JOIN (SELECT * 
                  FROM   [user] 
                  WHERE  [USER].userid = 12669) users 
         ON [USERs].bookid = library.bookid 
ORDER  BY [USERs].userid DESC, 
          [USERs].position, 
          library.position 
于 2012-05-15T14:48:06.940 回答