我有以下数据库表,其中包含有关人员,疾病和药物的信息:
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
从这些表中,我运行了一些关于哪些人服用哪种药物的统计数据 并有哪些疾病。由此我可以找出哪些模式很有趣 我要深入研究。例如,下面是我可能为疾病52找到的布尔模式的简化示例:
( (Drug 234 = false AND Drug 474 = true AND Drug 26 = false) OR
(Drug 395 = false AND Drug 791 = false AND Drug 371 = true) )
修改 这是另一个例子:
( (Drug 234 = true AND Drug 474 = true AND Drug 26 = false) OR
(Drug 395 = false AND Drug 791 = false AND Drug 371 = true) )
现在我想将此模式转换为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 || ???)
我需要在PostgreSql中使用它,但我认为任何给定的答案都可以从给定的数据库转换为PostgreSql。
对评论的回应
修改 我添加了自己的答案。任何人都可以提出一个更简单的答案吗?
答案 0 :(得分: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])
......等等。在这个例子中,我们要求服用药物474但不服用234的人。显然,你可以根据你的需要将条款与AND和OR分组。
除此之外:我发现很难看到所有的大写字母。我通常对SQL关键字使用大写,对表和列名称使用小写。
答案 1 :(得分:1)
答案 2 :(得分:1)
答案 3 :(得分:0)
请原谅任何错误,但我认为这样的事情会起作用(在T-SQL中):
SELECT col1, col2, col3...
FROM PERSON_T AS P, DRUG_T AS DR, DISEASE_T AS DI
WHERE disease_id = 52
AND P.person_id = DI.person_id
AND P.person_id = DR.person_id
AND drug_id NOT IN(234, 26)
AND drug_id = 474
AND disease_start_date < drug_start_date
UNION
SELECT col1, col2, col3...
FROM PERSON_T AS P, DRUG_T AS DR, DISEASE_T AS DI
WHERE disease_id = 52
AND P.person_id = DI.person_id
AND P.person_id = DR.person_id
AND drug_id NOT IN(791, 395)
AND drug_id = 371
AND disease_start_date < drug_start_date
现在不需要使用UNION,但为了便于阅读,我认为这是最简单的条件。也许这会引导你朝着正确的方向前进。
答案 4 :(得分:0)
SELECT per.person_id, per.name, per.gender
FROM person_t per
INNER JOIN disease_t dis
USING (person_id)
INNER JOIN drug_t drug
USING (person_id)
WHERE dis.disease_id = 52 AND drug.drug_start_date < dis.disease_start_date AND ((drug.drug_id IN (234, 474) AND drug.drug_id NOT IN (26)) OR (drug.drug_id IN (371) AND drug.drug_id NOT IN (395, 791)));
这将满足您的要求。最后的IN语句非常自我解释。
答案 5 :(得分:0)
答案 6 :(得分:0)
答案 7 :(得分:0)
答案 8 :(得分:0)
答案 9 :(得分:0)