Jay*_*ren 6 sql database join boolean-expression
我有以下数据库表,其中包含有关人员,疾病和药物的信息:
PERSON_T DISEASE_T DRUG_T
========= ========== ========
PERSON_ID DISEASE_ID DRUG_ID
GENDER PERSON_ID PERSON_ID
NAME DISEASE_START_DATE DRUG_START_DATE
DISEASE_END_DATE DRUG_END_DATE
Run Code Online (Sandbox Code Playgroud)
从这些表格中,我得到了一些关于哪些人服用哪种药物和哪些疾病的统计数据.从中我可以弄清楚哪些模式对我来说是有趣的深入研究.例如,下面是我可能为疾病52找到的布尔模式的简化示例:
( (Drug 234 = false AND Drug 474 = true AND Drug 26 = false) OR
(Drug 395 = false AND Drug 791 = false AND Drug 371 = true) )
Run Code Online (Sandbox Code Playgroud)
编辑: 这是另一个例子:
( (Drug 234 = true AND Drug 474 = true AND Drug 26 = false) OR
(Drug 395 = false AND Drug 791 = false AND Drug 371 = true) )
Run Code Online (Sandbox Code Playgroud)
现在我想将此模式转换为sql查询并找到匹配此模式的所有人.
例如,我想找到PERSON_T中患有该疾病的所有人((在出现症状之前没有服用药物234和26,但在出现症状之前确实服用了药物474)或者(在出现症状之前服用了药物371) ,但在出现症状之前没有药物791和395))
我如何将此模式转换回原始查询?
这是我的第一次尝试,但是我在第一个学期遇到困难:
SELECT * FROM PERSON_T, DRUG_T, DISEASE_T
WHERE DISEASE_ID = 52 AND
PERSON_T.PERSON_ID = DISEASE_T.PERSON_ID AND
PERSON_T.PERSON_ID = DRUG_T.PERSON_ID AND
(DRUG_T.DRUG_ID=234 AND (DRUG_T.DRUG_START_DATE>DISEASE_T.END_DATE || ???)
Run Code Online (Sandbox Code Playgroud)
我需要这个在PostgreSql中工作,但我认为任何给定的答案都可以从给定的数据库转换为PostgreSql.
对评论的回应
编辑 我添加了自己的答案.任何人都能想出一个更简单的答案吗?
对我来说,最简单(虽然丑陋)的解决方案是使用 EXISTS 和 NOT EXISTS 子句:
SELECT *
FROM PERSON_T INNER JOIN DISEASE_T
USING (PERSON_ID)
WHERE DISEASE_ID = 52
AND EXISTS (SELECT 1 FROM DRUG_T
WHERE DRUG_T.PERSON_ID = PERSON_T.PERSON_ID
AND DRUG_ID = 474
AND [time condition])
AND NOT EXISTS (SELECT 1 FROM DRUG_T
WHERE DRUG_T.PERSON_ID = PERSON_T.PERSON_ID
AND DRUG_ID = 234
AND [time condition])
Run Code Online (Sandbox Code Playgroud)
...等等。在示例中,我们询问的是服用过药物 474 但未服用药物 234 的人。显然,您可以根据需要使用 AND 和 OR 对子句进行分组。
旁白:我发现全部大写很难阅读。我通常使用大写字母表示 SQL 关键字,使用小写字母表示表名和列名。