PostgreSQL Cursor更新表

时间:2016-06-08 10:41:00

标签: postgresql cursor datediff

我有一张代表患者体检的表,它有检查ID和患者ID。

我希望逐行浏览表并获取每个患者ID并比较其不同的咨询,以确定它是否被视为&#34; new_attack&#34;。我正在处理疟疾疾病,我们认为每个患者在过去60天内接受过咨询,并且对于测试是积极的,并且是new_attack = falsenew_attack = true。< / p>

但是,当我通过表格时,我必须考虑专栏palufalci因为患者可以接受体检但对疟疾测试没有肯定,在这种情况下new_attack = false

以下是创建表格的代码:

CREATE TABLE public.tbl_diagnostiques_guy (
  id integer NOT NULL DEFAULT nextval('tbl_diagnostiques_guy_id_seq'::regclass),
  dateconsultation date,
  numeropatient character varying(13),
  palufalci boolean,
  new_attack boolean
);

我使用此查询计算每位患者的2次体检之间的datediff

SELECT id, numeropatient, palufalci,
    dateconsultation, NextDate,
    date(NextDate) - date(dateconsultation) as Diff, new_attack
FROM (
  SELECT id, numeropatient, palufalci, dateconsultation, new_attack,
         (SELECT  MIN(dateconsultation) 
          FROM    tbl_diagnostiques_guy T2
          WHERE   T2.numeropatient = T1.numeropatient
          AND     T2.dateconsultation > T1.dateconsultation
         ) AS NextDate
  FROM tbl_diagnostiques_guy T1) AS T
WHERE NextDate IS NOT NULL AND (date(NextDate) - date(dateconsultation) < 60)
GROUP BY id, numeropatient, palufalci, dateconsultation, NextDate, new_attack
ORDER BY numeropatient DESC;

结果是: here

现在我想知道如何更新表并获得我想要的结果。

1 个答案:

答案 0 :(得分:0)

从您的问题中可以看出,您希望使用值填充new_attack列。使用您的查询很容易做到这一点 - 尽管您设置new_attack值的逻辑似乎丢失了 - 但实际上使用lag() window function实际上有一个更优雅的形式:

SELECT id, numeropatient, palufalci, dateconsultation,
       CASE WHEN days IS NULL OR days > 60 THEN false
       ELSE palufalci AND old_test
       END AS new_attack
FROM (
  SELECT id, numeropatient, palufalci, lag(palufalci) OVER w AS old_test,
         dateconsultation, dateconsultation - lag(dateconsultation) OVER w AS days,
  FROM tbl_diagnostiques_guy
  WINDOW w AS (PARTITION BY numeropatient ORDER BY dateconsultation) ) sub;

运行该语句以验证它是否符合您的预期。如果满意,那么您可以轻松地将整个事情重新编写为UPDATE语句:

UPDATE tbl_diagnostiques_guy t
SET new_attack =
       CASE WHEN days IS NULL OR days > 60 THEN false
       ELSE palufalci AND old_test
       END
FROM (
  SELECT id, numeropatient, palufalci, lag(palufalci) OVER w AS old_test,
         dateconsultation, dateconsultation - lag(dateconsultation) OVER w AS days,
  FROM tbl_diagnostiques_guy
  WINDOW w AS (PARTITION BY numeropatient ORDER BY dateconsultation) ) sub
WHERE t.id = sub.id; -- add other join conditions as required

让我们更详细地看一下new_attack逻辑:

CASE WHEN days IS NULL OR days > 60 THEN false
ELSE palufalci AND old_test
END

第一行WHEN days IS NULL OR days > 60 THEN false表示:如果之前的咨询时间超过60天,或者这是第一次咨询(lag()函数将在第一次咨询时返回NULL,因为那里不是前一行),那么new_attack值为false

第二行palufalci AND old_test表示:如果在60天内进行了第二次咨询,则new_attacktrue true,前提和当前测试均为txtName.Text = txtName.Text .Replace((char) 0x2018, '\'') // &lsquo; ‘ .Replace((char) 0x2019, '\'') // &rsquo; ’ .Replace((char) 0x201C, '"') // &ldquo; “ .Replace((char) 0x201D, '"'); // &rdquo; ”