SQL select查询连接

时间:2015-11-20 16:57:13

标签: mysql sql inner-join select-query

下面是我的MYSQL表。我无法弄清楚MySQl查询是什么样的,每月只从父级中选择一行(按一个月中的最新日期)及其后续子行。因此,在给定的示例中,它应该从子表中返回ID为4,5,6,10,11,12

的行

enter image description here

4 个答案:

答案 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;