我的查询如下:
SELECT codes.id, (SELECT SUM(PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM a.end_date), EXTRACT(YEAR_MONTH FROM a.start_date))) months
FROM (
SELECT MIN(g.start_date) start_date, MAX(g.end_date) end_date
FROM (
SELECT @group_id := @group_id + (@end_date IS NULL OR o.start_date > @end_date) group_id,
start_date,
@end_date := DATE(CASE
WHEN (@end_date IS NULL OR o.start_date > @end_date) THEN o.end_date
ELSE GREATEST(o.end_date, @end_date)
END) end_date
FROM dates_range o
JOIN (SELECT @group_id := 0, @end_date := NULL) init
WHERE o.code_id = codes.id -- THIS CLAUSE DOES NOT WORK
ORDER BY o.start_date ASC
) g
GROUP BY g.group_id
) a) as sum_date_ranges
FROM codes
-- A LOT OF JOINs and WHEREs OF codes.id THAT I CAN NOT MOVE INSIDE THE NESTED TWO LEVEL SUBQUERY
正如注释中所写,WHERE
子句不起作用,但是我需要在嵌套的二级子查询中使用codes.id
。我该怎么办?
MySQL错误:
Unknown column 'codes.id' in 'where clause'
答案 0 :(得分:0)
无法从派生表访问外部表(简化一下,在您的情况下,这是任何需要别名的“子查询”,g
和{{ 1}})。
您必须使用a
在外部进行必要的操作。为此,您需要跟踪join
并将其传递到外部级别:
o.code_id
对于每个新的SELECT codes.id, sum_date_ranges.sum_date_ranges
FROM codes
JOIN
(SELECT a.code_id, SUM( ... ) as sum_date_ranges
(SELECT g.code_id, g.group_id, MIN( ... ), MAX( ... )
FROM ( SELECT o.code_id, @group_id = ...
FROM dates_range o ...
-- WHERE o.code_id = codes.id -- not required
ORDER BY o.code_id, o.start_date
) g
GROUP BY g.code_id, g.group_id
) a
GROUP BY a.code_id
) as sum_date_ranges
ON sum_date_ranges.code_id = codes.id
-- the rest of your joins and where-conditions
,您可能需要熟练使用@group_id = ...
才能从0重新开始,但是由于您似乎并没有在任何地方使用绝对值,因此可能没有关系。
这将为每个o.code_id
评估完整的派生表,然后丢弃它不需要的所有内容(可能会或可能不会成为数据的重要部分)。为了防止这种情况,您可以改为将外部条件放入查询中:
code_id
这假设您实际上只需要SELECT sum_date_ranges.code_id as id, sum_date_ranges.sum_date_ranges
-- from codes -- not required anymore, we get codes.id from derived table
FROM
(SELECT a.code_id, SUM( ... ) as sum_date_ranges
(SELECT g.code_id, g.group_id, MIN( ... ), MAX( ... )
FROM ( SELECT o.code_id, @group_id = ...
FROM dates_range o ...
WHERE o.code_id IN (SELECT codes.id
FROM codes
-- your join and where-conditions
)
ORDER BY o.code_id, o.start_date
) g
GROUP BY g.code_id, g.group_id
) a
GROUP BY a.code_id
) as sum_date_ranges
-- optionally in case you need other columns from codes
-- JOIN codes ON codes.id = sum_date_ranges.code_id
中的列codes.id
(并且您的codes
不会乘以行),但是在这方面您的查询可能已经简化了,所以当然,您仍然可以再次联接joins
(和其他表)以获取所需的列(但这里不再需要codes
条件)。
可能可以完全重写查询而无需派生表,但是可能需要进行大量修改并且不太可能使用变量。如果从头开始,这可能是最简单的方法(如果需要帮助,则需要提供完整的查询,示例数据,预期输出以及代码应执行的一些解释)。具体来说,如果您使用MySQL 8,则可能会使用window functions而不是变量来获得这种排名,总和,第一个和最后一个值,尽管看起来您毕竟仍然需要一个派生表。>