我有一个sql表如下:
+-----------+----------+----------+---------------+ | AccountID | PersonId | DoctorID | Admitdatetime | +-----------+----------+----------+---------------+ | 1 | 2 | 345 | 20090108 | | 2 | 3 | 53 | 20090109 | | 3 | 1 | 234 | 20090110 | | 4 | 2 | 345 | | +-----------+----------+----------+---------------+
此表格的每一行都像是admitdatetime
给出的患者访问。每个唯一记录由AccountID
日期列基本上是int
,并且是yyyymmdd
。因此,仅减去两个日期可能不正确,因为它不是日期时间。我刚刚检查过。
现在,我想对表中的每条记录做的是添加3列。一个是过去三个月,一个是过去6个月,一个是过去12个月。
列描述如下:
没有。一个DoctorID
在过去3个月中出现的案例。同样,没有。 DoctorID
在过去6个月中出现的案例。
我正在做这样的自我加入:
SELECT a.DoctorID, count(AccountID) FROM
Visits AS a INNER JOIN
Visits AS b ON a.DoctorId = b.DoctorId
WHERE a.admitdatetime - b.admitdatetime <= 90
以上我在3个月的案例中所做的,但我不认为这是正确的。我希望每个记录都没有。在此之前3,6,9个月,医生已经看到病例(AccountId
的数量)。因此,对于每个DoctorID
,该值会根据doctorID
所在的记录而变化,并且在该记录的admitdatetime
之前3,6,9个月,以便上面的代码只给我doctorID
一个值。这看起来并不正确。
我认为联接应按DoctorId, AccountId
分组,因为我需要将所有doctorid
加入到每条记录中,并且每条记录都由accountid
标识。然后将其加入doctorid
和accountid
。听起来不错吗?
答案 0 :(得分:0)
我建议使用相关子查询:
select v.*,
(select sum(case when v2.AdmitDate >= v.AdmitDate - interval '3 month'
then 1 else 0
end)
from visits v2
where v2.doctorid = v.doctorid
) as last3,
(select sum(case when v2.AdmitDate >= v.AdmitDate - interval '6 month'
then 1 else 0
end)
from visits v2
where v2.doctorid = v.doctorid
) as last6,
(select sum(case when v2.AdmitDate >= v.AdmitDate - interval '12 month'
then 1 else 0
end)
from visits v2
where v2.doctorid = v.doctorid
) as last12
from visits v;
我应该指出Postgres允许您简化这种语法:
(select sum((v2.AdmitDate >= v.AdmitDate - interval '3 month')::int)
from visits v2
where v2.doctorid = v.doctorid
) as last3,
在更新版本的Postgres中,您可以使用lateral join
将逻辑组合到一个子查询中。
编辑:
查询的合理简化是:
select v.*,
(select count(*)
from visits v2
where v2.doctorid = v.doctorid and v2.AdmitDate >= v.AdmitDate - interval '3 month'
) as last3,
(select count(*)
from visits v2
where v2.doctorid = v.doctorid and 2.AdmitDate >= v.AdmitDate - interval '6 month'
) as last6,
(select count(*)
from visits v2
where v2.doctorid = v.doctorid and v2.AdmitDate >= v.AdmitDate - interval '12 month'
) as last12
from visits v;