SELECT *
FROM (
`lecture` AS l
)
LEFT JOIN `professor` AS p ON `p`.`professor_id` = `l`.`professor_id`
WHERE `lecture_sem` = '20141'
AND (
lecture_name LIKE '%KEYWORD%'
OR lecture_code LIKE '%KEYWORD%'
OR p.professor_name LIKE '%KEYWORD%'
)
AND (
SELECT COUNT( DISTINCT s1.yoil, s1.start_time, s1.end_time )
FROM schedule AS s1
INNER JOIN schedule AS s2 ON ( s1.lecture_id
IN (
SELECT lecture_id
FROM timeitem
WHERE timetable_id =890
)
AND s2.yoil = s1.yoil
AND (
(
s1.start_time <= s2.start_time
AND s2.end_time <= s1.end_time
) )
AND s2.lecture_id = lecture_id # <-- HERE
)
) >0
LIMIT 0 , 30
我想使用这样的列:
s2.lecture_id = lecture_id
,或者
s2.lecture_id = l.lecture_id
所以我想在子查询中使用父列,但是会发生错误:
Column 'lecture_id' in on clause is ambiguous
我用Google搜索了关于这个问题的许多答案(“on clause is ambiguous”),他们说我应该将此查询替换为加入两个查询。但我不知道如何转换此查询。
答案 0 :(得分:2)
我相信以下是等效查询,但我没有测试过。
该技术是将相关子查询作为派生表移动到FROM子句中,以便它只运行一次,为每个lecture_id生成一个结果(因此为GROUP BY)。
我还考虑了时间表的子查询,我认为可以将其重写为JOIN。
我怀疑加入教授可能是一个内心加入 - 你如何在没有教授的情况下进行演讲?
SELECT l.*, p.*
FROM lecture AS l
INNER JOIN professor AS p ON p.professor_id = l.professor_id
INNER JOIN (
SELECT s2.lecture_id, COUNT( DISTINCT s1.yoil, s1.start_time, s1.end_time ) AS count
FROM schedule AS s1
INNER JOIN schedule AS s2 ON s2.yoil = s1.yoil
AND s1.start_time <= s2.start_time AND s2.end_time <= s1.end_time
INNER JOIN timeitem AS t ON s1.lecture_id = t.lecture_id
WHERE t.timetable_id = 890
GROUP BY s2.lecture_id
) AS c ON l.lecture_id = c.lecture_id
WHERE l.lecture_sem = '20141'
AND c.count > 0
AND (
l.lecture_name LIKE '%KEYWORD%'
OR l.lecture_code LIKE '%KEYWORD%'
OR p.professor_name LIKE '%KEYWORD%'
)
LIMIT 0 , 30
无论如何,即使查询不完美,它也会演示如何重构它以避免相关的子查询。
答案 1 :(得分:0)
您在代码中标识的行不是ON
子句。
相反,我认为错误是指以下部分。
AND (
SELECT COUNT( DISTINCT s1.yoil, s1.start_time, s1.end_time )
FROM schedule AS s1
INNER JOIN schedule AS s2 ON ( s1.lecture_id
IN (
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
SELECT lecture_id # <---- HERE
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FROM timeitem
WHERE timetable_id =890
)
您可以通过为timeitem
表创建别名并在列前添加此前缀来解决此问题:
IN (
SELECT ti.lecture_id
FROM timeitem as ti
WHERE ti.timetable_id =890
)
但正如Bill Karwin在答案中指出的那样,你还有其他需要解决的逻辑问题。