[英]Where clause with multi AND & OR conditions
I got a table agenda
in which the admin can make a reservation for him self or for someone else (another user).我有一个表格
agenda
,管理员可以在其中为他自己或其他人(另一个用户)进行预订。 If the admin make the reservation for him self in agenda.user_id
will be stored the id
of admin.如果管理员在议程中为他自己预订,
agenda.user_id
将存储管理员的id
。
In case that admin make a reservation for another person (another user) in agenda.user_id
will be stored the id
of the user for which the reservation will be made.如果管理员在议程中为另一个人(另一个用户)进行预订
agenda.user_id
将存储将为其进行预订的用户的id
。 The id
of the admin will be stored in another column agenda.booked_user
.管理员的
id
将存储在另一个列中agenda.booked_user
。
All the reservations are stored on agenda_users
table also.所有预订也存储在
agenda_users
表中。 agenda_users
has this columns: id
, agenda_id
, user_id
. agenda_users
有这些列: id
, agenda_id
ID ,用户user_id
。 The agenda_users.user_id
it refers to agenda.user_id
. agenda_users.user_id
它指的是agenda.user_id
。
I want to retrieve all the reservations made by the admin which has made reservations for himself and for other users also.我想检索已为自己和其他用户进行预订的管理员所做的所有预订。
I did a query with some AND & OR:我用一些 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
Cannot figure out the right solution to 'grab' all the reservations the admin has made for him self and other users.无法找出正确的解决方案来“获取”管理员为他自己和其他用户所做的所有预订。
solving the old-style-joins will leave you with this SQL:解决旧式连接会给你留下这个 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;
This SQL is almost human-readable (and understandable).这个 SQL 几乎是人类可读的(并且可以理解)。
EDIT: Added extra ()
because AND has higher precedence than OR.编辑:添加了额外的
()
,因为 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;
It is cleaner in my opinion to use UNION
instead of a very complex where conditions.在我看来,使用
UNION
而不是非常复杂的 where 条件更简洁。
Note that you know the user_id you are filtering for, therefore you don't need to join.请注意,您知道要过滤的 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
Don't forget to add the rest of the where conditions to both subqueries of the union不要忘记将 where 条件的 rest 添加到并集的两个子查询中
This is too long for a comment.评论太长了。 So I am posting this as an answer and may adjust it, once you clarify doubts about the data model.
因此,一旦您澄清对数据 model 的疑问,我将其发布为答案并可能会对其进行调整。
There is a parent table agenda
and it has a child table agenda_users
.有一个父表
agenda
,它有一个子表agenda_users
。 So one agenda has several users.所以一个议程有几个用户。 But the
agenda
table itself has two users, too.但是
agenda
表本身也有两个用户。 One is the person who made the reservation, but rather than using one column for that user, you are song sometimes one column and sometimes the other.一个是进行预订的人,但不是为该用户使用一列,您有时是一列,有时是另一列。 You say that when an admin makes a reservation for another user, the admin gets stored in the column
booked_user
, although it's obviously not the booked user, but the booking user.您说当管理员为另一个用户进行预订时,管理员将存储在列
booked_user
中,尽管显然不是预订用户,而是预订用户。 I wonder whether you have understoodthe data model yourself, because the explanation sounds just wrong.我不知道您是否自己理解了数据model,因为解释听起来很错误。
Then, an agenda
should typically be identified by its id
(hence the name), so the agenda_users
should be linked via its agenda_id
only.然后,
agenda
通常应由其id
(因此名称),因此agenda_users
应仅通过其agenda_id
ID 链接。 Are you sure that the user_id
of the two tables must match, too?您确定两个表的
user_id
也必须匹配吗? That would mean an agenda.id
is unique only in combination with a user_id
?这意味着一个
agenda.id
仅与一个user_id
结合是唯一的? It is possible, but doesn't seem likely.这是可能的,但似乎不太可能。
Your query has some issues, too.您的查询也有一些问题。
agenda.$user_id
is probably supposed to mean $user_id
only? agenda.$user_id
可能应该只表示$user_id
?AND
has precedence over OR
, so the checkout
and date_end
criteria will only works for the part after OR
.AND
优先于OR
,因此checkout
和date_end
标准仅适用于OR
之后的部分。checkout
and date_end
belong to? checkout
和date_end
属于什么表? I assume it's the agenda
table and will write my query accordingly, because you mentioned the columns of the agenda_users
table and these columns were not mentioned.agenda
表,并将相应地编写我的查询,因为您提到了agenda_users
表的列,而这些列没有被提及。 You want to select data from agenda
.您想从
agenda
中获取 select 数据。 So, do so, don't join another table.所以,这样做,不要加入另一个表。 If you have criteria based on the other table, then use
IN
or EXISTS
for the lookup.如果您有基于其他表的条件,则使用
IN
或EXISTS
进行查找。 In your case, though, - but I can only guess here - it seems you don't need the agenda_users
table at all.但是,就您而言,-但我只能在这里猜测-您似乎根本不需要
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.