下面是我的MYSQL表。我无法弄清楚MySQl查询是什么样的,每月只从父级中选择一行(按一个月中的最新日期)及其后续子行。因此,在给定的示例中,它应该从子表中返回ID为4,5,6,10,11,12
的行答案 0 :(得分:3)
我认为以下内容可以帮到你:
SELECT Child.id
FROM parent
INNER JOIN Child ON parent.id = child.parent_id
WHERE parent.`date` IN (SELECT max(`date`) FROM parent GROUP BY YEAR(`date`), MONTH(`date`))
有趣的部分是WHERE
子句,我们只抓取parent
表记录,其中date
是特定月/年组合的max(date)
。
答案 1 :(得分:2)
好的,让我们分成几部分:
首先,从parent
表中选择最大日期,按月分组:
select max(`date`) as max_date from parent group by last_day(`date`)
-- The "last_day()" function returns the last day of the month for a given date
然后,从父表中选择相应的行:
select parent.*
from parent
inner join (select max(`date`) as max_date from parent group by last_day(`date`)) as a
on parent.`date` = a.max_date
最后,选择child
表中的相应行:
select child.*
from child
inner join parent
on child.parent_id = parent.id
inner join (select max(`date`) as max_date from parent group by last_day(`date`)) as a
on parent.`date` = a.max_date;
您可以在此SQL fiddle上查看其工作原理。
修改强>
上述解决方案有效,但如果您的表很大,则可能会遇到问题,因为已连接的数据未编入索引。解决此问题的一种方法是创建一个临时表并使用此临时表来获得最终结果:
drop table if exists temp_max_date;
create temporary table temp_max_date
select max(`date`) as max_date
from parent
group by last_day(`date`);
alter table temp_max_date
add index idx_max_date(max_date);
-- Get the final data:
select child.*
from child
inner join parent
on child.parent_id = parent.id
inner join temp_max_date as a
on parent.`date` = a.max_date;
Here's the SQL fiddle for this second solution
临时表只能访问创建它们的连接,并在连接关闭或终止时被销毁。
请记住:在表格中添加适当的索引。
答案 2 :(得分:1)
使用此SQL:
SELECT * FROM Child WHERE PARENT_ID IN (
SELECT MAX(ID) FROM Parent GROUP BY LAST_DAY(DATE)
)
以下是工作的SQL小提琴:http://sqlfiddle.com/#!9/d8880/8
答案 3 :(得分:0)
这个解决方案笨拙,无法正确使用索引,但它比编写索引更容易...
SELECT a.*
, c.id
FROM parent a
JOIN
( SELECT DATE_FORMAT(date,'%Y-%m')yearmonth
, MAX(date) max_date
FROM parent
GROUP
BY yearmonth
) b
ON b.max_date = a.date
JOIN child c
ON c.parent_id = a.id;