[英]Where clause with multi AND & OR conditions
我有一个表格agenda
,管理员可以在其中为他自己或其他人(另一个用户)进行预订。 如果管理员在议程中为他自己预订, agenda.user_id
将存储管理员的id
。
如果管理员在议程中为另一个人(另一个用户)进行预订agenda.user_id
将存储将为其进行预订的用户的id
。 管理员的id
将存储在另一个列中agenda.booked_user
。
所有预订也存储在agenda_users
表中。 agenda_users
有这些列: id
, agenda_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
,因此checkout
和date_end
标准仅适用于OR
之后的部分。checkout
和date_end
属于什么表? 我假设它是agenda
表,并将相应地编写我的查询,因为您提到了agenda_users
表的列,而这些列没有被提及。 您想从agenda
中获取 select 数据。 所以,这样做,不要加入另一个表。 如果您有基于其他表的条件,则使用IN
或EXISTS
进行查找。 但是,就您而言,-但我只能在这里猜测-您似乎根本不需要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.