2014-02-28 233 views
2

我將幾個xml文件導入到我的數據庫中。每次調查我都有多個交易ID和多個varname,每個都有一個值。sql where子句查詢

我已經能夠得到我需要的結果,但我不知道如果我正確地做到這一點。 我不完全知道如何我會寫一個查詢來選擇出所需的調查IDS ..

where varname in ('age') and value >18 

會給我所有的調查IDS參與者超過18

舊的,但如果我有多個變量和有些是數字...所以我不能只寫> 18,如果我有其他變數,也是數字...

我怎麼能將值關聯到該varname?

SURVEY_ID VARNAME VALUE 
674078265 PROVID provider name 
674078265 SEX Female 
674078265 age 55 
674078265 SP Internal Med 
674078265 ID# 12345 
674111111 ADJSAMP Included 
674111111 PROVID provider name2 
674111111 SEX Male 
674111111 age 34 
674111111 SP Surgery 
674111111 ADJSAMP Included 
674111111 ID# 6789 
+0

什麼數據類型是值列? –

+0

歡迎來到EAV(實體屬性值)表的世界!根據整體設置,您可能可以進一步對此進行標準化,但調查是可能有用的領域之一。如果可以的話,我建議創建一個'VARNAME'表,這樣你就不會得到像'age','Age',''AGE','age'=「 #!*&business!「'。 –

回答

2
SELECT * 
FROM TableName 
WHERE SURVEY_ID IN (SELECT SURVEY_ID 
        FROM TableName 
        WHERE VARNAME = 'age' 
        AND VALUE > 18) 

或者更有效的方式將

SELECT * 
FROM TableName t 
WHERE EXISTS (SELECT 1 
       FROM TableName 
       WHERE SURVEY_ID = t.SURVEY_ID 
       AND VARNAME = 'age' 
       AND VALUE > 18) 

OR

SELECT t1.* 
FROM TABLE_Name t1 LEFT JOIN TABLE_Name t2 
ON t1.SURVEY_ID = t2.SURVEY_ID 
WHERE t2.VARNAME = 'age' 
AND t2.VALUE > 18 
0

擴展@ M.Ali答案居然回答你的問題 - 添加儘可能多的存在,你需要所有現場條件:

SELECT * 
FROM TableName t 
WHERE EXISTS (SELECT 1 
      FROM TableName 
      WHERE SURVEY_ID = t.SURVEY_ID 
      AND VARNAME = 'age' 
      AND VALUE > 18) 
    and EXISTS (SELECT 1 
      FROM TableName 
      WHERE SURVEY_ID = t.SURVEY_ID 
      AND VARNAME = 'sex' 
      AND VALUE = 'Male') 
0

我實際上會提供兩個答案的混合,而不僅僅是一個查詢,但爲什麼。

看起來你想要一個給定的調查相關聯的所有元素,只要它符合你正在尋找的特定標準......這,我會給M.Ali的第一個答案,但第二個基於多個標準,你可能會感興趣於

但是,爲了進一步分析數據,每個調查的多個記錄可能不是實際的......相反,我會用一個交叉表結果。爲了驗證記錄,這將是一個優化。

首先,從簡單查詢開始,獲取符合多個條件的調查。我會在所有這三個領域在表上的索引在這種情況下(SURVEY_ID,VARNAME,VALUE)

SELECT 
     s1.* 
    FROM 
     YourTable s1 
     JOIN (SELECT s2.SURVEY_ID 
          FROM YourTable s2 

           JOIN YourTable s3 
           on s2.survey_id = s3.survey_id 
           AND s3.varname = 'SEX' 
           AND s3.value = 'Male' 

           JOIN YourTable s4 
           on s2.survey_id = s4.survey_id 
           AND s3.varname = 'ADJSAMP' 
           AND s3.value = 'Included' 

          WHERE s2.VARNAME = 'age' 
          AND s2.VALUE > 18) PreQual 
     on s1.SURVEY_ID = PreQual.Survey_ID 

因此,內部查詢,你可以換在任何一種方式的標準,並增加額外加入更多標準(或更少)。無論你懷疑什麼是最小的結果標準,我會把「年齡」> 18的條款放在哪裏,並調整其他條款。

因此,內部查詢首先通過在同一個調查ID上添加額外連接(別名s3)來開始獲取年齡大於18的那些查詢,但不同的條件幾乎就像並排分析列一樣。如果它們不存在,整個調查將被忽略。找到符合條件的調查ID後,即會將其加入主表中以獲取所有行元素。

現在,使其更易於管理。放在每列的交叉標籤上。只需更改選擇字段標準併爲調查ID添加GROUP BY,但查詢的其餘部分將保持不變。

SELECT 
     s1.survey_id, 
     max(case when varname = 'PROVID' then value end) as Provider, 
     max(case when varname = 'SEX' then value end) as Gender, 
     max(case when varname = 'age' then value end) as Age, 
     max(case when varname = 'SP' then value end) as Specialty, 
     max(case when varname = 'ID#' then value end) as IDNumber, 
     max(case when varname = 'ADJSAMP' then value end) as AdjustSample 
    FROM 
     [rest of original query sample above] 
    GROUP BY 
     s1.survey_id 

現在,如果你沒有應用任何標準過濾,上面的查詢會爲您提供結果類似...

survey_id Provider  Gender Age Specialty  IDNumber AdjustSample 
674078265 provider name Female 55 Internal Med 12345  Included 
674111111 provider name2 Male 34 Surgery  6789  Included 
+0

這是非常有用的。我實際上只需要符合條件的調查ID,以便我可以使用該子集運行附加查詢。謝謝大家! – user3101182

+0

@ user3101182,你也可以接受你的輸入,建立最終的交叉表查詢ONCE,然後直接對列名而不是複雜的聯接直接有簡單的標準。對你來說可能是一個更好的解決方案。 – DRapp