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

Sql 从表中每人获得一个值(“截止日期前每组的最新数字”),sql,firebird,firebird1.5,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,

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

 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年1月至6月有权每月休假8小时,从2012年7月起,她有权每月休假10小时。换句话说,如果我发出日期为2012年1月31日的查询,我希望返回第1行和第3行;如果我发出2012年5月31日的查询,我希望返回第1行和第4行,如果我发出2012年8月31日的查询,我希望返回第2行和第4行

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

select therapist, max (illness), max (holiday)  
from budget
where curdate <= '2012-08-31'
group by therapist
2012年8月31日的查询将返回disease=8和holiday=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')

在这方面也有类似的问题,但似乎没有一个适用于我的情况。当然,如果我可以在没有聚合函数的情况下使用“group by”,生活会更轻松,但是Firebird和大多数DBMS都不支持这一点。

我认为应该是这样的:

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)

如果我正确理解了您的问题,我认为您需要:

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

这本质上是一个重复数据消除问题,因为如果您试图清理数据,使每个治疗师只有一行符合您描述的标准,您也会遇到同样的问题。这很少是简单的

也就是说,在你目前的情况下,你可以使用以下方法:

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]

我想你的意思是你想要2012年1月31日的第1行和第3行,对吗?@FacioRatio:没错。我已经编辑了这个问题。可能是的,但我的Firebird版本给了我以下错误标记未知-第5行,字符11。选择换句话说,它不允许我创建临时表“分组”。@No'amNewman您使用的是什么Firebird版本?此查询在Firebird 2上运行良好。5@No“2006年Firebird 2.0中引入了阿姆纽曼派生表,虽然我有一个治疗师表,但我不需要它用于特定的查询。您的答案返回预算表中的所有行。可能是的,但我的Firebird版本为我提供了以下未知错误标记-第5行,字符11。选择换句话说,它不允许我创建临时表“t”。
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]