如何将简单的布尔语句转换为SQL?

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.

对评论的回应

  1. 我修复了数据库表的格式.谢谢.
  2. 我需要能够获取任意布尔语句并将其转换为SQL.我们实际创建的布尔语句比我给出的示例要长得多.我创建的任何新表都将位于新数据库中,并且需要与原始表具有相同的模式.这种方式对最终用户来说,他们可以在新表上运行相同的代码,它的工作方式与在原始表上运行的相同.这是客户的要求.我希望我可以创建一个只对原始表进行查询的视图.如果我们无法使其工作,我可以创建表的副本并过滤数据,因为我将其复制到新表.我们没有使用神经网络进行分析.我们使用自己的自定义算法,比神经网络更好地扩展.
  3. Disease_Start_Date是患者获得疾病的日期,这可能是症状开始出现的时间.Disease_End_Date是当症状消失时可能恢复的人.
  4. Drug_start_date是该人开始服用药物的时间.Drug_end_date是指该人停止服用该药物的时间.

编辑 我添加了自己的答案.任何人都能想出一个更简单的答案吗?

Jus*_*n K 4

对我来说,最简单(虽然丑陋)的解决方案是使用 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 关键字,使用小写字母表示表名和列名。