【问题标题】:Oracle find record by multiple matching criteriaOracle通过多个匹配条件查找记录
【发布时间】:2021-03-17 10:44:36
【问题描述】:

我正在尝试通过两列中的多个匹配值来查找记录。

只是给你一个我正在尝试做的例子:我有一个保存在数据库中的表格,其中包含有关疾病的复选框,当患者入院时可以或不可以存在。

这些是这样的:

Acquistion Time: Admission [ ]  Follow-Up [ ]  Transfer [ ]  Discharge [ ]
Illness present? Yes [ ]  No [ ]

因此患者可以进行多项此类调查。

现在我要做的是:我必须找到在他们进入医院时不存在疾病的患者(入院和否的组合)但是在他们逗留期间发生了变化(后续和是的组合

我的想法是使用两个 EXISTS 语句,但没有成功(+ 运行时间真的很长):

编辑

我现在拥有的数据集(我一开始没有添加整个查询)看起来像这样(限于一种情况以使其可读):

CaseNumber CaseID Admission Date Acquisition Date Flag Checkbox
123456789 123 09.11.2020 13.11.2020 16:13 1 cbxAdmission
123456789 123 09.11.2020 13.11.2020 16:13 0 cbxFollowUp
123456789 123 09.11.2020 13.11.2020 16:13 0 cbxIllnessPresent
123456789 123 09.11.2020 13.12.2020 10:23 0 cbxAdmission
123456789 123 09.11.2020 13.12.2020 10:23 1 cbxFollowUp
123456789 123 09.11.2020 13.12.2020 10:23 1 cbxIllnessPresent
123456789 123 09.11.2020 20.11.2020 07:38 0 cbxAdmission
123456789 123 09.11.2020 20.11.2020 07:38 1 cbxFollowUp
123456789 123 09.11.2020 20.11.2020 07:38 0 cbxIllnessPresent

这是相应的查询:

SELECT DISTINCT
    f.FALLNR AS "Fall",
    f.FALLID,
    TO_CHAR(f.AUFNDAT, 'DD.MM.YYYY') AS "Aufnahmedatum",
    --cf.TEXT AS "Text",
    CONCAT(CONCAT(TO_CHAR(cp.MEDDATE, 'DD.MM.YYYY'), ' '), TO_CHAR(cp.MEDTIME, 'HH24:MI')) AS "Befundzeitpunkt",
    --cp.PRIMITIVUMNUMMER,
    --ck.NUMMER,
    cf2.FLAG,
    --cf2.WERT,
    cf3.CODE
FROM
    OS_CW.CW_PRIMITIVUM cp 
    INNER JOIN FALL f ON f.FALLID = cp.FALL
    INNER JOIN OS_CW.CW_KLASSE ck ON ck.NUMMER = cp.KLASSE
    LEFT JOIN OS_CW.CW_FELDTEXT cf ON cf.PRIMITIVUMNUMMER = cp.PRIMITIVUMNUMMER
    LEFT JOIN OS_CW.CW_FELDDATEN cf2 ON cf2.PRIMITIVUMNUMMER = cp.PRIMITIVUMNUMMER
    LEFT JOIN OS_CW.CW_FELDCODE cf3 ON cf3.NUMMER = cf2.FELDDEFINITION 
WHERE
    ck.MAPPENNUMMER = 16
    AND f.FALLNR = 123456789
    AND f.MEDICALCASESTATE IN (65366, 65369)
    AND f.CASEMARK IN (38140, 38142)
    AND EXTRACT(YEAR FROM f.ENTLDAT) = 2021
    AND cp.STORNIERT = 0
    AND (cf3.CODE = 'cbxAdmission' OR cf3.CODE = 'cbxFollowUp' OR cf3.CODE = 'cbxIllnessPresent')
GROUP BY f.FALLNR, f.FALLID, CONCAT(CONCAT(TO_CHAR(cp.MEDDATE, 'DD.MM.YYYY'), ' '), TO_CHAR(cp.MEDTIME, 'HH24:MI')), TO_CHAR(f.AUFNDAT, 'DD.MM.YYYY'), cf2.FLAG, cf3.CODE
ORDER BY CONCAT(CONCAT(TO_CHAR(cp.MEDDATE, 'DD.MM.YYYY'), ' '), TO_CHAR(cp.MEDTIME, 'HH24:MI')), cf3.CODE DESC

现在我需要一个查询,如果我已经描述的条件匹配,则返回 CaseNumber 和获取日期 - 这应该是这里的情况,因为它不存在于入院/第一次收购 (13.11.2021) 但它然后它进化并出现在下一次收购(2021 年 12 月 13 日)中,这是后续行动。

我想到了分析函数,但找不到适合我需要的函数(我不是 Oracle DBMS 中最有经验的人)。

如果(如果是的话 - 如何)这可以转化为查询,有什么想法吗?

感谢任何有用的回答!

【问题讨论】:

  • 样本数据和期望的结果真的很有帮助。你对数据的描述和问题中的代码大相径庭,这也令人困惑。

标签: sql database oracle


【解决方案1】:

我认为您可以将它们与或在最后条件中结合起来,如下所示:

AND EXISTS (
    SELECT *
    FROM OS_CW.CW_PRIMITIVUM cp2 
    JOIN OS_CW.CW_FELDTEXT cf4 ON cf4.PRIMITIVUMNUMMER = cp2.PRIMITIVUMNUMMER
    JOIN OS_CW.CW_FELDDATEN cf5 ON cf5.PRIMITIVUMNUMMER = cp2.PRIMITIVUMNUMMER
    JOIN OS_CW.CW_FELDCODE cf6 ON cf6.NUMMER = cf5.FELDDEFINITION 
    WHERE cp2.FALL = f.FALLID
    AND (((cf6.CODE = 'cbxAdmission' AND cf5.FLAG = 1) AND (cf6.CODE = 'cbxIllnessPresent' AND cf5.FLAG = 0))
    or ((cf6.CODE = 'cbxFollowUp' AND cf5.FLAG = 1) AND (cf6.CODE = 'cbxIllnessPresent' AND cf5.FLAG = 1)))

【讨论】:

  • @Max 如果问题还没有解决,请告诉我。
【解决方案2】:

好的,经过反复试验和逻辑思考,我设法将一个有效的查询放在一起,我只是使用INNER JOIN 来始终组合不同表之间的匹配条件。

最终结果是这样的(不要介意德语描述等)

 SELECT 
"Fall", 
"Vorname",
"Name",
"Geburtsdatum",
"Aufnahmedatum", 
"Befundzeitpunkt Aufnahme", 
"Erhebungart A", 
"Dekubitus vorh. b. Aufn." ,
"Befundzeitpunkte Folgeerhebungen",
"Erhebungsart F",
"Dekubitus vorh. b. Folgeerh."
FROM (
    SELECT DISTINCT 
        t1."Fall", 
        t1."Vorname",
        t1."Name",
        t1."Geburtsdatum",
        t1."Aufnahmedatum", 
        t1."Befundzeitpunkt Aufnahme", 
        t1."Erhebungsart" AS "Erhebungart A",
        t2."Flag" AS "Dekubitus vorh. b. Aufn.",
        LISTAGG(t3."Befundzeitpunkt Folgeerhebung", ', ') WITHIN GROUP (ORDER BY t3."Befundzeitpunkt Folgeerhebung") OVER (PARTITION BY t1."Fall") AS "Befundzeitpunkte Folgeerhebungen",
        t3."Erhebungsart" AS "Erhebungsart F",
        t4."Flag" AS "Dekubitus vorh. b. Folgeerh."
    FROM
        /* Checkbox "Dekubituserhebung zur Aufnahme" = TRUE */
        (SELECT DISTINCT
            f.FALLNR AS "Fall",
            np.VORNAME AS "Vorname",
            np.NAME AS "Name",
            TO_CHAR(np.GEBDAT, 'DD.MM.YYYY') AS "Geburtsdatum",
            TO_CHAR(f.AUFNDAT, 'DD.MM.YYYY') AS "Aufnahmedatum",
            CONCAT(CONCAT(TO_CHAR(cp.MEDDATE, 'DD.MM.YYYY'), ' '), TO_CHAR(cp.MEDTIME, 'HH24:MI')) AS "Befundzeitpunkt Aufnahme",
            DECODE(cf2.FLAG, 0, 'Nein', 1, 'Ja') AS "Flag",
            DECODE(cf3.CODE, 'cbxDekuZurAufnahme', 'Ersterhebung') AS "Erhebungsart"
        FROM 
            OS_CW.CW_PRIMITIVUM cp 
            INNER JOIN FALL f ON f.FALLID = cp.FALL
            INNER JOIN NATPERSON np ON f.PERSNR = np.PERSNR
            INNER JOIN OS_CW.CW_KLASSE ck ON ck.NUMMER = cp.KLASSE
            LEFT JOIN OS_CW.CW_FELDTEXT cf ON cf.PRIMITIVUMNUMMER = cp.PRIMITIVUMNUMMER
            LEFT JOIN OS_CW.CW_FELDDATEN cf2 ON cf2.PRIMITIVUMNUMMER = cp.PRIMITIVUMNUMMER
            LEFT JOIN OS_CW.CW_FELDCODE cf3 ON cf3.NUMMER = cf2.FELDDEFINITION 
        WHERE
            ck.MAPPENNUMMER = 16
            AND f.MEDICALCASESTATE IN (65366, 65369)
            AND f.CASEMARK IN (38140, 38142)
            AND EXTRACT(YEAR FROM f.ENTLDAT) = 2021
            AND cp.STORNIERT = 0
            AND (cf3.CODE = 'cbxDekuZurAufnahme' AND cf2.FLAG = 1)
        ) t1
    
        INNER JOIN 
        
        /* Checkbox "Dekubituserhebung zur Aufnahme" = TRUE UND Checkbox "Dekubitus vorhanden" = FALSE - kein Dekubitus bei Aufnahmeerehbung */
        (SELECT DISTINCT
            f.FALLNR AS "Fall",
            CONCAT(CONCAT(TO_CHAR(cp.MEDDATE, 'DD.MM.YYYY'), ' '), TO_CHAR(cp.MEDTIME, 'HH24:MI')) AS "Befundzeitpunkt Aufnahme",
            DECODE(cf2.FLAG, 0, 'Nein', 1, 'Ja') AS "Flag",
            DECODE(cf3.CODE, 'cbxDekubitusVorhanden', 'Dekubitus vorhanden') AS "Dekubitus vorhanden"
        FROM 
            OS_CW.CW_PRIMITIVUM cp 
            INNER JOIN FALL f ON f.FALLID = cp.FALL
            INNER JOIN OS_CW.CW_KLASSE ck ON ck.NUMMER = cp.KLASSE
            LEFT JOIN OS_CW.CW_FELDTEXT cf ON cf.PRIMITIVUMNUMMER = cp.PRIMITIVUMNUMMER
            LEFT JOIN OS_CW.CW_FELDDATEN cf2 ON cf2.PRIMITIVUMNUMMER = cp.PRIMITIVUMNUMMER
            LEFT JOIN OS_CW.CW_FELDCODE cf3 ON cf3.NUMMER = cf2.FELDDEFINITION 
        WHERE
            ck.MAPPENNUMMER = 16
            AND f.MEDICALCASESTATE IN (65366, 65369)
            AND f.CASEMARK IN (38140, 38142)
            AND EXTRACT(YEAR FROM f.ENTLDAT) = 2021
            AND cp.STORNIERT = 0
            AND (cf3.CODE = 'cbxDekubitusVorhanden' AND cf2.FLAG = 0)
        ) t2
        
        ON t1."Fall" = t2."Fall"
        AND t1."Befundzeitpunkt Aufnahme" = t2."Befundzeitpunkt Aufnahme"
        
        INNER JOIN
        
        /* Checkbox "Dekubituserhebung als Folgeerhebung" = TRUE */
        (SELECT DISTINCT
            f.FALLNR AS "Fall",
            CONCAT(CONCAT(TO_CHAR(cp.MEDDATE, 'DD.MM.YYYY'), ' '), TO_CHAR(cp.MEDTIME, 'HH24:MI')) AS "Befundzeitpunkt Folgeerhebung",
            DECODE(cf2.FLAG, 0, 'Nein', 1, 'Ja') AS "Flag",
            DECODE(cf3.CODE, 'cbxDekuFolgeerhebung', 'Folgeerhebung') AS "Erhebungsart"
        FROM 
            OS_CW.CW_PRIMITIVUM cp 
            INNER JOIN FALL f ON f.FALLID = cp.FALL
            INNER JOIN OS_CW.CW_KLASSE ck ON ck.NUMMER = cp.KLASSE
            LEFT JOIN OS_CW.CW_FELDTEXT cf ON cf.PRIMITIVUMNUMMER = cp.PRIMITIVUMNUMMER
            LEFT JOIN OS_CW.CW_FELDDATEN cf2 ON cf2.PRIMITIVUMNUMMER = cp.PRIMITIVUMNUMMER
            LEFT JOIN OS_CW.CW_FELDCODE cf3 ON cf3.NUMMER = cf2.FELDDEFINITION 
        WHERE
            ck.MAPPENNUMMER = 16
            AND f.MEDICALCASESTATE IN (65366, 65369)
            AND f.CASEMARK IN (38140, 38142)
            AND EXTRACT(YEAR FROM f.ENTLDAT) = 2021
            AND cp.STORNIERT = 0
            AND (cf3.CODE = 'cbxDekuFolgeerhebung' AND cf2.FLAG = 1)
        ) t3
        
        ON t1."Fall" = t3."Fall"
        AND t2."Fall" = t3."Fall"
        
        INNER JOIN 
        
        /* Checkbox "Dekubituserhebung als Folgeerhebung" = TRUE UND Checkbox "Dekubitus vorhanden" = TRUE - Dekubitus während Aufenthalt entwickelt */
        (SELECT DISTINCT
            f.FALLNR AS "Fall",
            CONCAT(CONCAT(TO_CHAR(cp.MEDDATE, 'DD.MM.YYYY'), ' '), TO_CHAR(cp.MEDTIME, 'HH24:MI')) AS "Befundzeitpunkt Folgeerhebung",
            DECODE(cf2.FLAG, 0, 'Nein', 1, 'Ja') AS "Flag",
            DECODE(cf3.CODE, 'cbxDekubitusVorhanden', 'Dekubitus vorhanden') AS "Dekubitus vorhanden"
        FROM 
            OS_CW.CW_PRIMITIVUM cp 
            INNER JOIN FALL f ON f.FALLID = cp.FALL
            INNER JOIN OS_CW.CW_KLASSE ck ON ck.NUMMER = cp.KLASSE
            LEFT JOIN OS_CW.CW_FELDTEXT cf ON cf.PRIMITIVUMNUMMER = cp.PRIMITIVUMNUMMER
            LEFT JOIN OS_CW.CW_FELDDATEN cf2 ON cf2.PRIMITIVUMNUMMER = cp.PRIMITIVUMNUMMER
            LEFT JOIN OS_CW.CW_FELDCODE cf3 ON cf3.NUMMER = cf2.FELDDEFINITION 
        WHERE
            ck.MAPPENNUMMER = 16
            AND f.MEDICALCASESTATE IN (65366, 65369)
            AND f.CASEMARK IN (38140, 38142)
            AND EXTRACT(YEAR FROM f.ENTLDAT) = 2021
            AND cp.STORNIERT = 0
            --AND CONCAT(CONCAT(TO_CHAR(cp.MEDDATE, 'DD.MM.YYYY'), ' '), TO_CHAR(cp.MEDTIME, 'HH24:MI')) = '16.09.2020 16:47'
            AND (cf3.CODE = 'cbxDekubitusVorhanden' AND cf2.FLAG = 1)
        ) t4    
        
        ON t3."Befundzeitpunkt Folgeerhebung" = t4."Befundzeitpunkt Folgeerhebung"
        AND t3."Fall" = t4."Fall"
)
ORDER BY "Aufnahmedatum", "Fall", TO_DATE("Befundzeitpunkt Aufnahme", 'DD.MM.YYYY HH24:MI')

【讨论】:

    猜你喜欢
    • 2016-11-13
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    相关资源
    最近更新 更多