【问题标题】:MySQL whitelist queryMySQL白名单查询
【发布时间】:2015-04-26 09:33:44
【问题描述】:

我正在制作一个自定义白名单,其中我的主表是 book_list,包含 id - 主键和其他不重要的列。另一个表是白名单,其中包含来自 book_list 的外键和另一个键是 user_id。

book_list 表

--------------
| id          |
---------------
| 10          |
| 11          |
| 12          |
| 13          |
---------------

白名单表

---------------------------
| book_list_id   | user_id |
----------------------------
| 10             | 1       |
| 10             | 2       |
----------------------------

所以当 user_id 1 正在浏览时,他/她应该看到所有的书 (10, 11, 12, 13),但是如果 id 5 的用户查看他应该只看到 book_list ids (11, 12, 13)

我的查询是这样的,但如果每个 book_id 只有一个 id 可用,它就可以工作。

SELECT * FROM book_list bl
LEFT JOIN whitelist w ON bl.id = w.book_list_id AND w.user_id <> 1
WHERE w.book_list_id IS NULL

注意:我总是从会话中获得 user_id,这就是为什么它是硬编码的。

【问题讨论】:

  • 我认为您需要某种子查询来检查user_id 是否存在于该W.book_list_id

标签: mysql sql


【解决方案1】:
SELECT *
FROM book_list
LEFT JOIN whitelist
  ON (whitelist.book_list_id = book_list.id)
WHERE (COALESCE(whitelist.user_id, 1) = 1)

已编辑以包含解释

条件同时执行两件事。如果whitelist 中没有该书的记录,则COALESCE 函数将返回用户的ID。如果在whitelist 中有该书的记录,则条件将阻止发生任何匹配,除非用户的 id 附加到该书。

【讨论】:

  • 谢谢!同时非常简单和强大。
  • 这是一个有趣的解决方案。但请记住,如果存在 ID 为 1 的用户,这是否会导致错误。相反,我会使用可能的用户 ID 范围之外的其他数字,例如 0 或 -1。
  • 实际上,1 将是查询的参数,您可以使用适合查询的任何 user_id
【解决方案2】:

您所需的查询实际上包含两组不同的结果:1) 未定义白名单的图书和 2) 具有白名单但当前用户有权访问的图书。要获得正确的结果,您需要将这两个部分分解,然后在最后将它们联合起来。

SELECT distinct bl.id FROM book_list bl 
LEFT JOIN whitelist w1 ON bl.id = w1.book_list_id AND w.user_id <> 1
INNER JOIN whitelist w2 ON bl.id = w2.book_list_id AND w.user_id = 1
WHERE w1.book_list_id IS NULL
UNION
SELECT distinct bl.id FROM book_list bl 
LEFT JOIN whitelist w ON bl.id = w.book_list_id
WHERE w.book_list_id IS NULL

第一个查询排除用户 1 未列入白名单的所有图书,并包括用户 1 列入白名单的所有图书。第二个查询返回所有未列入白名单的图书。

【讨论】:

    猜你喜欢
    • 2015-02-17
    • 1970-01-01
    • 2014-07-24
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多