要更新的 PostgreSQL 游标 table
PostgreSQL Cursor to update table
我有一个table代表病人的医疗检查,它有检查的ID和病人的ID。
我想运行逐行table,取每个患者的ID,比较其不同的会诊,看是否属于"new_attack"。我正在处理疟疾疾病,我们认为每个在过去 60 天内接受过咨询并且对测试呈阳性的患者都是旧病例,并且 new_attack = false
,否则 new_attack = true
.
但是我在进行 table 时必须考虑 palufalci
栏,因为患者可以进行体检但疟疾检测结果不呈阳性,在这种情况下 new_attack = false
.
这是创建 table 的代码:
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
);
我使用这个查询来计算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
现在我想知道如何更新 table 并获得我想要的结果。
从你的问题看来,你想用值填充 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()
函数会returnNULL
对于第一次咨询,因为没有前一行),则 new_attack
值为 false
.
第二行palufalci AND old_test
表示:如果在60天内有第二次咨询那么new_attack
就是true
只有之前和现在的测试都是true
.
我有一个table代表病人的医疗检查,它有检查的ID和病人的ID。
我想运行逐行table,取每个患者的ID,比较其不同的会诊,看是否属于"new_attack"。我正在处理疟疾疾病,我们认为每个在过去 60 天内接受过咨询并且对测试呈阳性的患者都是旧病例,并且 new_attack = false
,否则 new_attack = true
.
但是我在进行 table 时必须考虑 palufalci
栏,因为患者可以进行体检但疟疾检测结果不呈阳性,在这种情况下 new_attack = false
.
这是创建 table 的代码:
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
);
我使用这个查询来计算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
现在我想知道如何更新 table 并获得我想要的结果。
从你的问题看来,你想用值填充 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()
函数会returnNULL
对于第一次咨询,因为没有前一行),则 new_attack
值为 false
.
第二行palufalci AND old_test
表示:如果在60天内有第二次咨询那么new_attack
就是true
只有之前和现在的测试都是true
.