繁体   English   中英

具有多个 AND & OR 条件的 Where 子句

[英]Where clause with multi AND & OR conditions

我有一个表格agenda ,管理员可以在其中为他自己或其他人(另一个用户)进行预订。 如果管理员在议程中为他自己预订, agenda.user_id将存储管理员的id

如果管理员在议程中为另一个人(另一个用户)进行预订agenda.user_id将存储将为其进行预订的用户的id 管理员的id将存储在另一个列中agenda.booked_user

所有预订也存储在agenda_users表中。 agenda_users有这些列: idagenda_id ID ,用户user_id agenda_users.user_id它指的是agenda.user_id

我想检索已为自己和其他用户进行预订的管理员所做的所有预订。

我用一些 AND & OR 进行了查询:

SELECT agenda.* 
FROM agenda,agenda_users 
WHERE agenda_users.agenda_id=agenda.id 
AND (agenda_users.user_id=$user_id 
AND agenda_users.user_id=agenda.user_id) 
OR (agenda_users.user_id=agenda.user_id 
AND agenda.booked_user=agenda.$user_id) 
AND checkout IS NULL 
AND NOW() < DATE_ADD(date_end, INTERVAL 6 HOUR) ORDER BY type ASC,date_start ASC

无法找出正确的解决方案来“获取”管理员为他自己和其他用户所做的所有预订。

解决旧式连接会给你留下这个 SQL:

SELECT agenda.* 
FROM agenda
INNER JOIN agenda_users ON agenda_users.user_id=agenda.user_id AND agenda_users.agenda_id=agenda.id
WHERE 
  (agenda_users.user_id=$user_id) OR (agenda.booked_user=agenda.$user_id) 
  AND checkout IS NULL 
  AND NOW() < DATE_ADD(date_end, INTERVAL 6 HOUR) ORDER BY type ASC,date_start ASC;

这个 SQL 几乎是人类可读的(并且可以理解)。

编辑:添加了额外的() ,因为 AND 的优先级高于 OR。

SELECT agenda.* 
FROM agenda
INNER JOIN agenda_users ON agenda_users.user_id=agenda.user_id AND agenda_users.agenda_id=agenda.id
WHERE 
  ((agenda_users.user_id=$user_id) OR (agenda.booked_user=agenda.$user_id)) 
  AND checkout IS NULL 
  AND NOW() < DATE_ADD(date_end, INTERVAL 6 HOUR) ORDER BY type ASC,date_start ASC;

在我看来,使用UNION而不是非常复杂的 where 条件更简洁。

请注意,您知道要过滤的 user_id,因此您不需要加入。

/* The ones for admin created by the user */
SELECT
agenda.*
FROM
agenda A
WHERE
A.user_id = $user_id

UNION ALL

/* the ones where the admin created it, but not for itself */
SELECT
agenda.*
FROM
agenda A
WHERE
A.booked_user_id = $user_id
AND A.user_id <> $user_id

不要忘记将 where 条件的 rest 添加到并集的两个子查询中

评论太长了。 因此,一旦您澄清对数据 model 的疑问,我将其发布为答案并可能会对其进行调整。

有一个父表agenda ,它有一个子表agenda_users 所以一个议程有几个用户。 但是agenda表本身也有两个用户。 一个是进行预订的人,但不是为该用户使用一列,您有时是一列,有时是另一列。 您说当管理员为另一个用户进行预订时,管理员将存储在列booked_user中,尽管显然不是预订用户,而是预订用户。 我不知道您是否自己理解了数据model,因为解释听起来很错误。

然后, agenda通常应由其id (因此名称),因此agenda_users应仅通过其agenda_id ID 链接。 您确定两个表的user_id也必须匹配吗? 这意味着一个agenda.id仅与一个user_id结合是唯一的? 这是可能的,但似乎不太可能。

您的查询也有一些问题。

  • agenda.$user_id可能应该只表示$user_id
  • 括号也可能是错误的,因为AND优先于OR ,因此checkoutdate_end标准仅适用于OR之后的部分。
  • 那你就错过了预选赛。 这不会使查询出错,但会使其更难阅读。 checkoutdate_end属于什么表? 我假设它是agenda表,并将相应地编写我的查询,因为您提到了agenda_users表的列,而这些列没有被提及。

您想从agenda中获取 select 数据。 所以,这样做,不要加入另一个表。 如果您有基于其他表的条件,则使用INEXISTS进行查找。 但是,就您而言,-但我只能在这里猜测-您似乎根本不需要agenda_users表。

SELECT * 
FROM agenda
WHERE (user_id = $user_id OR booked_user = $user_id)
AND checkout IS NULL 
AND NOW() < DATE_ADD(date_end, INTERVAL 6 HOUR)
ORDER BY type, date_start;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM