从表中获取每人一个值(“截止日期前最新的每组人数”)

时间:2012-08-10 17:44:43

标签: sql firebird firebird1.5

在我的数据库中,有一个名为“预算”的表定义如下

 CREATE TABLE BUDGET (
  ID INTEGER NOT NULL,
  THERAPIST INTEGER,
  CURDATE DATE,
  ILLNESS SMALLINT,
  HOLIDAY SMALLINT);

  ALTER TABLE BUDGET ADD PRIMARY KEY (ID);

该表的目的是存储一个月治疗师有权享受病假和定期休假的小时数。

该表格具有以下值

ID: 1, THERAPIST: 36, CURDATE: 01/01/2012, ILLNESS:8, HOLIDAY: 8
ID: 2, THERAPIST: 36, CURDATE: 01/07/2012, ILLNESS:8, HOLIDAY: 10
ID: 3, THERAPIST: 74, CURDATE: 01/01/2012, ILLNESS:8, HOLIDAY: 8
ID: 4, THERAPIST: 74, CURDATE: 01/03/2012, ILLNESS:8, HOLIDAY: 10

我想写一个查询,每个治疗师返回一行,最新数据(上述数据显示,治疗师36在2012年6月1日有权享受每月8小时假期,以及7 / 2012年她有权每月10小时)。换句话说,如果我发出日期为31/01/2012的查询,我希望得到第1行和第3行;如果我发布日期为31/05/2012的查询,我希望返回第1行和第4行,如果我发布日期为31/08/2012的查询,我希望返回第2行和第4行。

以下查询为每个治疗师提供了一行,但它给了我最大的疾病和假期值,这不一定是我想要的。

select therapist, max (illness), max (holiday)  
from budget
where curdate <= '2012-08-31'
group by therapist

表格中应该有第五行

ID: 5, THERAPIST: 74, CURDATE: 01/07/2012, ILLNESS: 6, HOLIDAY: 6
在2012年8月31日查询将返回疾病= 8和假期= 10,即使它们都应该是6。

我尝试了以下查询,但这只返回一行

select therapist, illness, holiday
from budget
where curdate =
(select max (curdate) from budget b
 where b.therapist = budget.therapist
 and b.curdate <= '2012-08-31')

在SO上有类似的问题,但它们似乎都不适用于我的情况。当然,如果我可以使用'group by'而不使用聚合函数来生活会更容易,但Firebird(以及大多数DBMS)不支持此功能。

3 个答案:

答案 0 :(得分:2)

如果我理解你的问题,我想你想要:

select
    b.*
from
    budget b
    join (
        select
            therapist,
            max(curdate) as maxdate
        from
            budget
        where 
            curdate <= '2012-08-31'
        group by
            therapist
    ) grouped on grouped.therapist = b.therapist and grouped.maxdate = b.curdate

答案 1 :(得分:1)

这实际上是一个重复数据删除问题,因为如果您尝试清理数据时遇到同样的问题,那么每个治疗师只有一行符合您所描述的标准。这很简单。

那就是说,你可以在目前的情况下使用这些东西:

select b.id, b.therapist, t.[curdate], b.illness, b.holiday
from budget b
inner join
(
    select therapist, MAX([curdate]) as [curdate]
    from BUDGET
    where [CURDATE] <= '2012-08-31'
    group by THERAPIST
) t on b.therapist = t.therapist and b.[CURDATE] = t.[curdate]

答案 2 :(得分:-1)

我认为会是这样的:

select * from therapist t
join budget a
on t.therapist=a.therapist
where id in (
select first 1 ID from BUDGET b
where 
b.theraphist=t.therapist and
b.curdate <= '2012-08-31'
order by curdate desc)