【问题标题】:Querying MySQL result set for existence of a particular value查询 MySQL 结果集是否存在特定值
【发布时间】:2023-11-20 00:43:02
【问题描述】:

这里是 MySQL 8.x。我有以下表格:

[users] (users in the system)
===
user_id
user_username
user_password_enc
user_first_name
user_last_name

[events] (CRUDdable things the users can participate in)
===
event_id
event_name
event_date
event_location

[event_roles] (coarse-grained, event-specific roles that users can be assigned to)
===
event_role_id
event_role_name
event_role_label    -- ex: EVENT_ADMIN, EVENT_REP, EVENT_FOLLOWER

[event_permissions] (granular permissions that get assigned to roles)
===
event_permission_id
event_permission_name
event_permission_label    -- ex: CAN_VIEW_LOCATION, CAN_CHANGE_DATE, CAN_CHANGE_LOCATION, CAN_CANCEL_EVENT

[event_permissions_x_roles] (crosswalk table mapping permissions to roles)
===
event_permissions_x_role_id
event_permission_id
event_role_id

[event_user_roles] (which users are assigned to which event roles)
===
event_user_role_id
event_id
user_id
event_role_id

我现在想编写一个询问以下问题的查询:

user_id = 234 是否拥有CAN_CHANGE_LOCATIONevent_id=123 的权限?

迄今为止我最好的尝试:

SELECT
  event_permission_label
FROM
  event_permissions_x_roles
INNER JOIN
  event_permissions
ON
  event_permissions_x_roles.event_permission_id = event_permissions.event_permission_id
WHERE
  event_role_id = (
    SELECT
      event_role_id
    FROM
      event_user_roles
    WHERE
      user_id = 234
      AND
      event_id = 123
  );

但是,这只会给我一个event_permission_labels 的列表,user_id=234 拥有event_id=123

接近我想要的,但我希望我的查询更进一步并检查该列表以查看 CAN_CHANGE_LOCATION 是否是该列表的一部分。我不知道是否有办法编写它以使其返回布尔值 true/false(是的,用户 是否 对给定事件具有所需的权限;或者用户 没有 等)。谁能发现我的不足之处?

【问题讨论】:

    标签: mysql mysql-8.0 ansi-sql


    【解决方案1】:

    示意图:

    SELECT EXISTS ( SELECT NULL
                    FROM {joined tables set}
                    WHERE t1.user_id = 234 
                      AND t2.event_permission_label = 'CAN_CHANGE_LOCATION'
                      AND t3.event_id = 123 ) 
    

    【讨论】:

    • 感谢@Akina (+1),SELECT EXISTS ... 会返回布尔真/假输出吗?为什么是内部SELECT NULL?这有什么作用?
    • @hotmeatballsoup SELECT EXISTS ... 会返回布尔真/假输出吗? MySQL 中不存在布尔数据类型,查询返回 1 或 0。为什么内部SELECT NULL? 输出列表中写入的内容无关紧要 - SELECT NULL, SELECT '', SELECT 'the row exists' 甚至 SELECT 1,'y',NOW() - EXISTS 只检查行的存在,而不是其内容。有人使用 SELECT 0 或 SELECT 1... 但我更喜欢 NULL。