簡體   English   中英

我將如何編寫此SQL查詢?

[英]How would I write this SQL query?

我有以下表格:

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

我想編寫一個查詢,輸入一個疾病ID,並為數據庫中的每個人返回一行,其中一列是性別,一列是他們是否曾經患過該病,一列是每種葯物其中指明了他們在感染該疾病之前是否服用了該葯物。 IE true表示drug_start_date <disease_start_date。 False表示Drug_start_date> disease_start_date或此人從未服用過該特定葯物。

當前,我們從數據庫中提取所有數據,並使用Java創建具有所有這些值的2D數組。 我們正在研究將此邏輯移入數據庫。 是否可以創建一個查詢,該查詢將返回我想要的結果集,還是必須創建一個存儲過程? 我們使用的是Postgres,但是我認為另一個數據庫的SQL答案很容易轉換為Postgres。

根據提供的信息:

   SELECT p.name,
          p.gender,
          CASE WHEN d.disease_id IS NULL THEN 'N' ELSE 'Y' END AS had_disease,
          dt.drug_id
     FROM PERSON p
LEFT JOIN DISEASE d ON d.person_id = p.person_id
                   AND d.disease_id = ?
LEFT JOIN DRUG_T dt ON dt.person_id = p.person_id
                   AND dt.drug_start_date < d.disease_start_date

..但是除了drug_id列外,會有很多行看起來都是重復的。

您實質上是在尋找使用葯物創建交叉表查詢的方法。 盡管有很多OLAP工具可以做到這一點(在其他各種數據切片和切分中),但是在傳統SQL中做這樣的事情並不容易(通常,如果沒有這些工具,就不可能做到)除了最簡單的方案外,其他所有方法都具有某種程序語法)。

使用SQL進行此操作時,基本上有兩個選項(更准確地說,您有一個選項,以及從中派生的另一個更復雜但靈活的選項):

  1. 在查詢中使用一系列CASE語句來生成代表每種葯物的列。 這需要提前知道變量值列表(即葯物)
  2. 使用過程SQL語言(例如T-SQL)來動態構造一個查詢,該查詢如上所述使用case語句,但還要從數據本身獲取值列表。

這兩個選項實質上具有相同的作用,您只是在第二個選項中犧牲了簡便性和易於維護性來換取靈活性。

例如,使用選項1:

select
    p.NAME,
    p.GENDER,
    (case when d.DISEASE_ID is null then 0 else 1 end) as HAD_DISEASE,
    (case when sum(case when dr.DRUG_ID = 1 then 1 else 0 end) > 0 then 1 else 0 end) as TOOK_DRUG_1,
    (case when sum(case when dr.DRUG_ID = 2 then 1 else 0 end) > 0 then 1 else 0 end) as TOOK_DRUG_2,
    (case when sum(case when dr.DRUG_ID = 3 then 1 else 0 end) > 0 then 1 else 0 end) as TOOK_DRUG_3

from PERSON_T p

left join DISEASE_T d on d.PERSON_ID = p.PERSON_ID and d.DISEASE_ID = @DiseaseId
left join DRUG_T dr on dr.PERSON_ID = p.PERSON_ID and dr.DRUG_START_DATE < d.DISEASE_START_DATE

group by p.PERSON_ID, p.NAME, p.GENDER, d.DISEASE_ID

如您所知,這超出了一些潛在值,因此會有些費力。

另一個選擇是動態構造此查詢。 我不知道PostgreSQL及其具有的程序功能(如果有),但是總體過程如下:

  1. 收集潛在的DRUG_ID值列表以及各列的名稱
  2. 准備三個字符串值:SQL前綴(第一個與葯物相關的CASE語句之前的所有內容,SQL填充文本(最后一個與葯物相關的CASE語句之后的所有內容)和動態部分
  3. 通過基於先前檢索到的列表組合葯物CASE語句來構建動態部分
  4. 將它們組合成單個(希望有效)的SQL語句並執行

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM