我想请求您帮助解决我几个小时以来一直困扰的问题。我只会插入解决问题所需的有关它们的信息。
基本上,我有四个表,我需要这个查询。
表1:门票。包含有关某些事件的行 罚单。具有以下属性: t_id , atNight 。
表2: ticketintervals 。这张票有多长时间了。 Attr。: ti_id , t_id , startDate , endDate
表3:票证分配。机票是谁的人 分配给,连接表。 Attr。: ta_id , person_id , 的 ti_id
表4:事件。它包含各种事件,发生在那里 晚上,肯定是有票。 Attr。: e_id , person_id , happenAtNight , start_date , end_date
要做到这一点,我需要考虑以下事项:
select * from tickets t, ticketintervals tint, ticketassignments t_ass, events e
where t.atNight = 1
and t.t_id = tint.t_id
and tint.ti_id = t_ass.ti_id
and t_ass.person_id = e.person_id
and e.happenedAtNight = 1
and date_format(tint.startDate,'%Y-%m-%d') != date_format(e.start_date,'%Y-%m-%d')
and date_format(tint.endDate,'%Y-%m-%d') != date_format(e.end_date,'%Y-%m-%d')
;
但是,这会将与事件日期不同的所有票证间隔与日期配对,因为可能存在atNight并且不属于某个事件的票证,但属于一个人属于一个事件。所以这种方式我似乎也获得了自己的票,有他们的间隔,但我只希望在没有属于他们的时间间隔的票时出现事件。
关键点,现在非常简短:我只希望看到晚上没有门票的活动。
我对如何处理这个问题感到很困惑,我已经看过INNER JOIN和许多其他方法,但我似乎无法掌握如何将这种逻辑连接到MySQL方式。
答案 0 :(得分:0)
由于您要列出事件,因此您必须先查询此表,然后加入您需要进行过滤的其他表:
SELECT e.* FROM events e
LEFT JOIN ticketassignments ta ON e.person_id = ta.person_id
LEFT JOIN ticketintervals ti ON ta.ti_id = ti.ti_id
LEFT JOIN tickets t ON ti.t_id = t.t_id
如果您在结果中需要其他表格信息,只需将其添加到SELECT语句中,例如:
SELECT e.*, ta.person_id, ti.*
然后过滤仅在晚上发生的事件
WHERE e.happenedAtNight = 1
然后确保将票证间隔和事件中的日期仅与夜间也发生的票证进行比较。不要比较ticket.atNight = 0
时的日期,但如果ticket.atNight = 1
:
AND (t.atNight = 0 OR (t.atNight = 1
AND DATE_FORMAT(ti.startDate,'%Y-%m-%d') != DATE_FORMAT(e.start_date,'%Y-%m-%d')
AND DATE_FORMAT(ti.endDate,'%Y-%m-%d') != DATE_FORMAT(e.end_date,'%Y-%m-%d')
));
以下是生成的SQL:
SELECT e.* FROM events e
LEFT JOIN ticketassignments ta ON e.person_id = ta.person_id
LEFT JOIN ticketintervals ti ON ta.ti_id = ti.ti_id
LEFT JOIN tickets t ON ti.t_id = t.t_id
WHERE e.happenedAtNight = 1
AND (t.atNight = 0 OR (t.atNight = 1
AND DATE_FORMAT(ti.startDate,'%Y-%m-%d') != DATE_FORMAT(e.start_date,'%Y-%m-%d')
AND DATE_FORMAT(ti.endDate,'%Y-%m-%d') != DATE_FORMAT(e.end_date,'%Y-%m-%d')
));