我有一个由7个表组合的select语句
SELECT * (//instead of * i put in my code the proper columns i need from the selected tabls)
FROM
ev_events_eve
LEFT JOIN ev_events_multilang_evmulti ON ev_events_multilang_evmulti.event_evmulti = ev_events_eve.id_eve
LEFT JOIN ev_schedule_sch ON ev_schedule_sch.event_id_sch = ev_events_eve.id_eve
LEFT JOIN ev_events_type_et ON ev_schedule_sch.event_type_id_sch = ev_events_type_et.id_et
LEFT JOIN ev_events_type_multilang_etmulti ON ev_events_type_multilang_etmulti.idevent_type_etmulti = ev_events_type_et.id_et
LEFT JOIN ev_schedule_multilang_schmulti ON ev_schedule_multilang_schmulti.id_schedule_schmulti = ev_schedule_sch.id_sch
LEFT JOIN ev_timetable_tt ON ev_timetable_tt.schedule_id_tt = ev_schedule_sch.id_sch AND ev_timetable_tt.event_id_tt = ev_events_eve.id_eve
WHERE (ev_events_eve.active_eve = 1 AND ev_schedule_multilang_schmulti.iso_code_lang_schmulti = '{$current_language}' AND ev_schedule_sch.active_sch = 1) AND
ev_timetable_tt.end_date_tt > CURDATE() OR (ev_timetable_tt.weekday_tt = DAYNAME(CURDATE()) AND ev_timetable_tt.end_date_tt > CURDATE()) OR ev_timetable_tt.specific_date_tt > CURDATE()
ORDER BY ev_timetable_tt.start_date_tt ASC LIMIT 3
这句话忽略了where子句的问题,每次我使用mysql我用来创建示例sql语句由两个或三个表组成,左边或内部正常连接,我需要有人和我讨论这个问题,它可以让我进一步看看我的代码中没有提到的东西,但是我知道上面的代码不足以让任何人跟我一起处理这个问题,但我需要有人可以跟我讨论
我使用以下信息更新了问题
主要业务规则:
ev_events_eve
(事件实体,如id,logo,标语,开头和结尾
整个活动的日期)
ev_events_multilang_evmulti
(主要事件的多语言表
表格如名称(en,fr,gr ..等),描述......等)ev_schedule_sch
(调度实体,如id,事件表的外键)ev_schedule_multilang_schmulti
(主要的多语言表
时间表)ev_timetable_tt
(存储与之相关的开始和结束日期及时间
ev_schedule_sch表)ev_events_multilang_evmulti
通过外国与主表相关
键ev_schedule_sch related
通过外键ev_schedule_multilang_schmulti
与ev_schedule_sch
表格相关
外键ev_timetable_tt
通过外键与ev_schedule_sch
相关我需要编写一个语句来从事件表中检索传入的3行(假设我需要检索最新的3行,因为你没有所有字段的完整模式,后来我们可以在WHERE子句:))加上这3行还从调度表中检索与事件表中每一行相关的6行 所以估计的结果必须是这样的 假设我有4个事件
我只需要检索上述3个事件和相关信息,如上所述
答案 0 :(得分:2)
我只是猜测问题出在查询的OR
部分。我刚刚在查询中更改了这部分:
AND (
ev_timetable_tt.end_date_tt > CURDATE()
OR (ev_timetable_tt.weekday_tt = DAYNAME(CURDATE()) AND ev_timetable_tt.end_date_tt > CURDATE())
OR ev_timetable_tt.specific_date_tt > CURDATE()
)
可能你想这样做:(我给了别名以使其更具可读性)
SELECT *
FROM ev_events_eve e
LEFT JOIN ev_events_multilang_evmulti eml ON eml.event_evmulti = e.id_eve
LEFT JOIN ev_schedule_sch es ON es.event_id_sch = e.id_eve
LEFT JOIN ev_events_type_et et ON es.event_type_id_sch = et.id_et
LEFT JOIN ev_events_type_multilang_etmulti emel ON emel.idevent_type_etmulti = et.id_et
LEFT JOIN ev_schedule_multilang_schmulti ems ON ems.id_schedule_schmulti = es.id_sch
LEFT JOIN ev_timetable_tt ett ON ett.schedule_id_tt = es.id_sch AND ett.event_id_tt = e.id_eve
WHERE (e.active_eve = 1 AND ems.iso_code_lang_schmulti = '{$current_language}' AND es.active_sch = 1)
AND
(
ett.end_date_tt > CURDATE()
OR (ett.weekday_tt = DAYNAME(CURDATE()) AND ett.end_date_tt > CURDATE())
OR ett.specific_date_tt > CURDATE()
)
ORDER BY ett.start_date_tt ASC
LIMIT 3
如果您更喜欢语法(没有表别名):
SELECT * (//instead of * i put in my code the proper columns i need from the selected tabls)
FROM
ev_events_eve
LEFT JOIN ev_events_multilang_evmulti ON ev_events_multilang_evmulti.event_evmulti = ev_events_eve.id_eve
LEFT JOIN ev_schedule_sch ON ev_schedule_sch.event_id_sch = ev_events_eve.id_eve
LEFT JOIN ev_events_type_et ON ev_schedule_sch.event_type_id_sch = ev_events_type_et.id_et
LEFT JOIN ev_events_type_multilang_etmulti ON ev_events_type_multilang_etmulti.idevent_type_etmulti = ev_events_type_et.id_et
LEFT JOIN ev_schedule_multilang_schmulti ON ev_schedule_multilang_schmulti.id_schedule_schmulti = ev_schedule_sch.id_sch
LEFT JOIN ev_timetable_tt ON ev_timetable_tt.schedule_id_tt = ev_schedule_sch.id_sch AND ev_timetable_tt.event_id_tt = ev_events_eve.id_eve
WHERE (ev_events_eve.active_eve = 1 AND ev_schedule_multilang_schmulti.iso_code_lang_schmulti = '{$current_language}' AND ev_schedule_sch.active_sch = 1)
AND (
ev_timetable_tt.end_date_tt > CURDATE()
OR (ev_timetable_tt.weekday_tt = DAYNAME(CURDATE()) AND ev_timetable_tt.end_date_tt > CURDATE())
OR ev_timetable_tt.specific_date_tt > CURDATE()
)
ORDER BY ev_timetable_tt.start_date_tt ASC LIMIT 3
答案 1 :(得分:0)
将LEFT JOIN
与WHERE
条件结合使用,NULL
条件要求LEFT JOIN
这些表格中的LEFT JOIN
值无法使用WHERE
1}}。您必须在[whatever] OR NULL
条件中指定值为WHERE
或将ON
条件指定为JOIN
的{{1}}。
例如:
... WHERE ... (ev_schedule_sch.active_sch = 1 OR ev_schedule_sch.active_sch IS NULL) ...
或者
... LEFT JOIN ev_schedule_sch ON ev_schedule_sch.event_id_sch = ev_events_eve.id_eve AND ev_schedule_sch.active_sch = 1 ...
答案 2 :(得分:0)
首先,我也相信where子句中的日期条件应该被包装以封装它。如果不是,则应用第一部分,然后在第一个“OR”合格时完全忽略它。下一个。你有许多LEFT JOIN,这意味着只要左侧的记录合格,只有RTIONAL边表中的记录可选。但是,一旦您针对所述右侧表向WHERE子句添加条件,它就会抛出“LEFT”限定条件。您应该将该条件移动到LEFT JOIN条件而不是where子句(我已经调整过)。
您的原始查询稍微清理一下,使用别名并更正日期条件的括号,这样您就不会得到错误的结果,但是通过WHERE子句显示为隐含,将其转换为NORMAL INNER join。
SELECT *
FROM
ev_events_eve EE
LEFT JOIN ev_events_multilang_evmulti ELANG
ON EE.id_eve = ELANG.event_evmulti
LEFT JOIN ev_schedule_sch SCHED
ON EE.id_eve = SCHED.event_id_sch
LEFT JOIN ev_events_type_et ETYPE
ON SCHED.event_type_id_sch = ETYPE.id_et
LEFT JOIN ev_events_type_multilang_etmulti ETMLANG
ON ETYPE.id_et = ETMLANG.idevent_type_etmulti
LEFT JOIN ev_schedule_multilang_schmulti SMS
ON SCHED.id_sch = SMS.id_schedule_schmulti
LEFT JOIN ev_timetable_tt TIMET
ON SCHED.id_sch = TIMET.schedule_id_tt
AND EE.id_eve = TIMET.event_id_tt
WHERE
( EE.active_eve = 1
AND SMS.iso_code_lang_schmulti = '{$current_language}'
AND SCHED.active_sch = 1 )
AND ( TIMET.end_date_tt > CURDATE()
OR ( TIMET.weekday_tt = DAYNAME(CURDATE())
AND TIMET.end_date_tt > CURDATE())
OR TIMET.specific_date_tt > CURDATE() )
ORDER BY
TIMET.start_date_tt ASC LIMIT 3
这里调整的查询是为了保持各自的LEFT JOIN,注意你的标准所在的差异。
SELECT *
FROM
ev_events_eve EE
LEFT JOIN ev_events_multilang_evmulti ELANG
ON EE.id_eve = ELANG.event_evmulti
LEFT JOIN ev_schedule_sch SCHED
ON EE.id_eve = SCHED.event_id_sch
AND SCHED.active_sch = 1
LEFT JOIN ev_events_type_et ETYPE
ON SCHED.event_type_id_sch = ETYPE.id_et
LEFT JOIN ev_events_type_multilang_etmulti ETMLANG
ON ETYPE.id_et = ETMLANG.idevent_type_etmulti
LEFT JOIN ev_schedule_multilang_schmulti SMS
ON SCHED.id_sch = SMS.id_schedule_schmulti
AND SMS.iso_code_lang_schmulti = '{$current_language}'
LEFT JOIN ev_timetable_tt TIMET
ON SCHED.id_sch = TIMET.schedule_id_tt
AND EE.id_eve = TIMET.event_id_tt
AND ( TIMET.end_date_tt > CURDATE()
OR ( TIMET.weekday_tt = DAYNAME( CURDATE() )
AND TIMET.end_date_tt > CURDATE() )
OR TIMET.specific_date_tt > CURDATE() )
WHERE
EE.active_eve = 1
ORDER BY
TIMET.start_date_tt ASC LIMIT 3
最后一点说明。您的ORDER BY引用了“ev_TimeTable_tt”(别名为TIMET)表,这对我来说意味着您总是期望只有在此表中可以找到明显的匹配项。如果是这样,事实上这应该是一个内部联接而不是一个左联合。
由于进入“EV_TIMETABLE_TT”表需要从计划表中查找,我希望这也是INNER JOIN要求。
因此,通过LEFT与INNER连接的澄清,您可能需要调整为这些的组合。不知道你的数据,我真的无法进一步指导。