根据日期加入表

时间:2015-03-27 18:23:01

标签: mysql

我有两个表,一个是公司列表,另一个是公司在申请和开始日期截止日期前做广告的工作清单。

有些公司不会宣传任何工作,有些公司只会在截止日期之前完成工作,有些公司只会有现场工作,有些公司会有过去和现场申请。

我希望能够在查询结果中显示的是所有公司的列表,它们具有最近的截止日期,按截止日期排序。所以结果可能看起来像这样(如果今天是2015-01-01)。

对不起,我错了。我希望能够做的是找到下一个截止日期,如果没有未来的截止日期,则显示最后一个截止日期。因此,在下面的第一个表中,BillyCo截止日期已过,但显示了下一个BuffyCo截止日期。在BillyCo案例中,有更早的截止日期,但在BuffyCo案例中,有早期和晚期截止日期。

id   name     title     date
==   ====     =====     ====
1    BobCo    null      null
2    BillCo   Designer  2014-12-01
3    BuffyCo  Admin     2015-01-31

因此,BobCo根本没有工作,BillCo的截止日期已经过去,BuffyCo将来会有截止日期。

问题在于BillCo可能有这样的一系列工作:

id   title     date        desired hit
==   =====     ====        ===========
1    Coder     2013-12-01
2    Manager   2014-06-30
3    Designer  2012-12-01  <--

BuffyCo可能有:

id   title     date        desired hit
==   =====     ====        ===========
1    Magician  2013-10-01
2    Teaboy    2014-05-19
3    Admin     2015-01-31  <--
4    Writer    2015-02-28

所以,我可以这样做:

select * from (
    select * from firms
    left join jobs on firms.id = jobs.firmid
    order by date desc) 
as t1 group by firmid;

或者,限制由日期标准加入或返回的作业,但我似乎无法获得我想要的记录。即上述查询将返回:

id   name     title     date
==   ====     =====     ====
1    BobCo    null      null
2    BillCo   Designer  2014-12-01
3    BuffyCo  Writer    2015-02-28

对于BuffyCo,它返回Writer作业而不是Admin作业。

使用SQL查询是不可能的?任何建议都表示赞赏,提前谢谢。

4 个答案:

答案 0 :(得分:0)

您的问题的修订使其相当棘手,但仍可以完成。试试这个:

select 
  closest_job.*, firm.name
from
  firms
  left join (
    select future_job.*
    from
      (
        select firmid, min(date) as mindate
        from jobs
        where date >= curdate()
        group by firmid
      ) future
      inner join jobs future_job
        on future_job.firmid = future.firmid and future_job.date = future.mindate

    union all

    select past_job.*
    from
      (
        select firmid, max(date) as maxdate
        from jobs
        group by firmid
        having max(date) < curdate()
      ) past
      inner join jobs past_job
        on past_job.firmid = past.firmid and past_job.date = past.maxdate
  ) closest_job
    on firms.id = closest_job.firmid

答案 1 :(得分:0)

我认为这可能是你需要的,你需要:

1) calculate the delta for all of your jobs between the date and the  current date finding the min delta for each firm.
2) join firms to jobs only on where firm id's match and where the calculated min delta for the firm matches the delta for the row in jobs.

    SELECT f.id, f.name, j.title,j.date
    FROM firms f LEFT JOIN 
        (SELECT firmid,MIN(abs(datediff(date, curdate())))) AS delta 
         FROM jobs 
         GROUP BY firmid) d 
    ON f.id = d.firmid 
    LEFT JOIN jobs j ON f.id = j.id AND d.delta = abs(datediff(j.date, curdate())))) ;

答案 2 :(得分:0)

您希望使用类似于(next upcoming, last expired)的{​​{3}}的内容制作outer join

SELECT * FROM firms LEFT JOIN (

  -- fetch the "groupwise" record
  jobs NATURAL JOIN (
    -- using the relevant date for each firm
    SELECT   firmid, MAX(closest_date) date
    FROM     (

               -- next upcoming deadline
               SELECT   firmid, MIN(date) closest_date
               FROM     jobs
               WHERE    date >= CURRENT_DATE
               GROUP BY firmid

             UNION ALL

               -- most recent expired deadline
               SELECT   firmid, MAX(date)
               FROM     jobs
               WHERE    date <  CURRENT_DATE
               GROUP BY firmid

             ) closest_dates
    GROUP BY firmid
  ) selected_dates

) ON jobs.firmid = firms.id

这实际上会为您提供所有作业,这些作业具有每家公司的最佳截止日期。如果要将结果限制为每个此类组的不确定记录,可以将GROUP BY firms.id添加到最后。

答案 3 :(得分:0)

我认为这符合我的需要:

select * from (
    select firms.name, t2.closest_date from firms
    left join
           (
           select * from (
           --get first date in the future
           SELECT   firmid, MIN(date) closest_date
           FROM     jobs
           WHERE    date >= CURRENT_DATE
           GROUP BY firmid

         UNION ALL

           -- most recent expired deadline
           SELECT   firmid, MAX(date)
           FROM     jobs
           WHERE    date <  CURRENT_DATE
           GROUP BY firmid) as t1

        -- order so latest date is first
        order by closest_date desc) as t2 
     on firms.id = t2.firmid

     -- group by eliminates all but latest date
     group by firms.id) as t3
order by closest_date asc;

感谢您对此的所有帮助