在SQL表

时间:2015-11-12 21:48:17

标签: sql postgresql

我有一个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标识。然后将其加入doctoridaccountid。听起来不错吗?

1 个答案:

答案 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;