查询列出每个2-uple字段的单行

时间:2014-10-20 17:36:09

标签: mysql

我有3张桌子。 表1用户, 表2 researchReq, 表3研究

researchReq表有一些要求,我用它来检查用户是否适合特定的研究(如min_agemax_age等)和int字段(num_of_days)。 research表有一个用于researchReq的FK,一个用户的FK,一个日期字段和一些更多的信息。在那些适合任何researchReq的用户中,我需要那些最后research个寄存器超过researchReq.num_of_days的所有用户以及那些没有任何research注册的用户。< / p>

e.g。

User
# | age
1 | 20
2 | 19
3 | 21

researchReq
# | min_age | max_age | num_of_days
1 | 15      | 25      | 20
2 | 25      | NULL    | 30

research
# | req_id | user_id | date
1 | 1      |  3      | 2014-08-20
2 | 1      |  3      | 2014-09-20
3 | 1      |  3      | 2014-10-20
4 | 1      |  2      | 2014-08-20
5 | 1      |  2      | 2014-09-20

在这种情况下,所有3个用户都适合researchReq #1

* min_age和max_age可以为空。如果它们为空,我需要在检查用户是否适合时不予理会

user_id | researchReq_id | last
1       | 1              | null
2       | 1              | 30

用户#1没有任何注册,所以&#39;最后&#39;是空的。

用户#2最后一次注册超过20天,所以我列出了他和他的间隔。

由于用户#3的research的最后一个注册日期不超过20天,我不需要他。

我试过这样的事情:

select ur.user_id, ur.req_id ,datediff(curdate(),ri.date) as last
from
     (
      select u.id as user_id, r.id as req_id, r.num_of_days as n_days
      from user u 
      join researchReq r
          on (r.min_age is null or datediff(curdate(),u.age) >= r.min_age)
          and (r.max_age is null or datediff(curdate(),u.age) <= r.max_age)
     ) as ur
left join research ri
    on ur.user_id = ri.user_id and ur.req_id = ri.req_id
having last > ur.n_days

但我遇到了问题。此查询列出了每个用户的所有research ri寄存器,我只需要每个ri.user_idri.req_id的最后日期的寄存器(如复合PK)。我不能使用group by user_id,因为它可能有两个或多个区别ri.req_id

我只是不知道该怎么做。 Ty提供任何帮助,抱歉我的英语不好。

@edit

如果用户使用FK研究2个或更多的researchReq,此查询将给出所有researchReq的min(datediff())。我需要一个接一个,例如:

user_id | researchReq_id | last
1       | 1              | null
2       | 1              | 30
2       | 2              | 15

查询返回

user_id | researchReq_id | last
1       | 1              | null
2       | 1              | 15
2       | 2              | 15

1 个答案:

答案 0 :(得分:0)

我并非100%确定我了解您的要求,但这至少会使用您提供的数据重现您正在寻找的答案。

select u.user_id, r.id as researchReq_id, u.last from (
  select u.id as user_id, u.age, min(datediff(now(), date)) as last
      from user u 
      left join research r on r.user_id = u.id
      group by u.id
      having last is null or last > 20) as u
join researchReq r
on (r.min_age is null or u.age >= r.min_age)
          and (r.max_age is null or u.age <= r.max_age)

Link to SQL Fiddle