2011-02-17 130 views
3

澄清計算BMI從身高/體重表

在通過你的答案的工作和閱讀你這個問題的解釋,我有以下的補充。

  • 我需要生成整個BMI歷史記錄,而不是單個值。
  • 兩個表中的每個值都需要與其他表中的相關值配對(如果可能)。

簡單的問題

鑑於PatientHeight的條目,並在其PatientWeight的EntryDate當前PatientHeight EntryDate和以前PatientHeight EntryDate介於所有條目計算BMI(身體質量指數)。這是真的,除非PatientWeight中的EntryDates> PatientHeight中的任何EntryDates。在這種情況下,請使用最新的PatientHeight條目來計算BMI。

對於PatientHeight中的每個條目,計算PatientWeight中所有適當的相應值的BMI(體重指數)。

一些邏輯:

  • PatientHeight的EntryDate是< = PatientWeight的EntryDate配對
  • PatientHeight有一個與PatientWeight一對多的關係
  • PatientHeight必須考慮到當上PatientHeight和使用EntryDate它作爲一個下邊界時匹配EntryThates在患者體重

我有一個函數co mpute BMI,這只是一個如何最好地將兩個表中的數據配對的問題。

注:這必須通過存儲過程來完成的,我不能改變表

 
PatientHeight 
PersonID 
EntryDate 
Inches 

9783 | 01/01/2010 | 75in 
9783 | 01/01/2009 | 74in 

 
PatientWeight 
PersonID 
EntryDate 
Pounds 

9783 | 01/01/2011 | 179lbs 
9783 | 01/01/2010 | 175lbs 
9783 | 12/01/2010 | 174lbs 
9783 | 11/01/2010 | 178lbs 
9783 | 01/01/2009 | 174lbs 
9783 | 12/01/2009 | 174lbs 
9783 | 11/01/2009 | 178lbs 

所以

除了每一行迭代中PatientWeight和查詢對於PatientHeight中適用的條目,然後計算BMI,有沒有什麼奇特的加入來正確配對數據?

這將是理想的:

 
9783 | 01/01/2011 | 75in | 178lbs 
9783 | 01/01/2010 | 75in | 175lbs 
9783 | 12/01/2010 | 75in | 174lbs 
9783 | 11/01/2010 | 75in | 178lbs 
9783 | 01/01/2009 | 74in | 174lbs 
9783 | 12/01/2009 | 74in | 174lbs 
9783 | 11/01/2009 | 74in | 178lbs 

我的最終查詢

下面是它的核心反正。似乎到目前爲止工作。

Insert Into @PatientWeightRet 
    Select 
     * 
    From 
    (
     Select 
      TransactionID, 
      EncounterID, 
      EntryDate, 
      ISNULL(CONVERT(NUMERIC(18,2),dbo.fnBmi(Inches, Pounds)), -1) AS BMI 
     From 
     (
      Select Distinct 
       W.TransactionID, 
       W.PatientID, 
       W.EntryDate, 
       W.EncounterID, 
       W.Pounds, 
       (-- For Every Weight 
        Select Top 1 --Get the first Entry 
         H.Inches 
        From 
         @PatientHeight AS H -- From Patient Height 
        Where 
         H.EntryDate <= W.EntryDate-- Who's Date is less than or equal to the Weight Date 
         AND W.EntryDate > -- and the Weight Date is greater than (the previous height date) 
         (
          ISNULL 
          (
           (
            Select Top 1 -- the first 
             EntryDate -- date 
            From 
             @PatientHeight -- from patientHeight 
            Where 
             EntryDate < H.EntryDate -- who's entry date is less than the current height date 
            Order BY EntryDate Desc, TransactionID DESC 
           ) 
          , '01/01/1800') -- if we're at the bottom, return really old date 
         ) 
        Order By H.EntryDate Desc, H.TransactionID DESC 
       ) AS Inches 
      From 
       PatientWeight AS W 
      Where 
       PatientID = @PatientID 
       AND Active = 1 
     ) tmp 
    ) tmp2 
    Where 
     BMI != -1 
    Order By EntryDate DESC, TransactionID DESC 
+0

有點偏題:爲什麼要用兩張表?這是一個家庭作業問題嗎? – moonman239 2015-10-26 21:24:54

+0

@ moonman239 - 這是一個要求。最初的設計由一張桌子組成,但用例顯示體重比身高更頻繁(因爲人們傾向於停止生長)。從那裏決定兩張桌子會更好。即使我們用一張桌子去[重量|高度],我們仍然需要解決同樣的問題並插入任何'NULL'高度。此外,我們無法自動填充數據庫中的這些值,因爲我們需要區分生成的值和用戶輸入的值,特別是在多個權重條目中添加/刪除高度時。 – 2015-11-03 18:59:23

回答

1
SELECT W.PersonID, 
     W.EntryDate, 
     (
      SELECT TOP 1 H.Inches 
       FROM PatientHeight AS H 
       WHERE W.PersonID = H.PersonId 
        AND H.EntryDate <= W.EntryDate 
       ORDER BY H.EntryDate DESC 
     ) AS Inches 
     W.Pounds 
    FROM PatientWeight AS W 
0

類似下面應該做的伎倆(未測試)。

SELECT P.PaitenId 
,  W.EntryDate 
,  P.Inches 
,  W.Pounds 
FROM (
    SELECT p.PatientId 
    ,  p.EntryDate AS EntryDate 
    ,  MIN(p2.EntryDate) as NextEntryDate 
    FROM PatientHeight p 
    LEFT JOIN PatientHeight p2 
    ON p.PatientID = p2.PatientID 
    AND p2.EntryDate > p.EntryDate 
    GROUP BY p.PatientId 
    , p.EntryDate 
) P 
JOIN PaitentWeight W 
ON P.PatientId = W.PatientId 
AND W.EntryDate BETWEEN P.EntryDate AND P.NextEntryDate 
0
SELECT 
    w.PersonID, 
    w.EntryDate, 
    Inches = MIN(h.Inches) 
    w.Pounds 
FROM PatientWeight w 
    LEFT JOIN PatientHeight h 
    ON w.PersonID = h.PersonID AND w.EntryDate >= h.EntryDate 
0

像這樣的事情

select 
     curr.personid, curr.entrydate, wgt.entrydate WeightDate, 
     dbo.CalcBMI(curr.Inches, wgt.Pounds) as BMI 
from 
    (Select top 1 * from PatientHeight 
     where personid= @personid 
     order by entrydate desc) curr 
outer apply 
    (select top 1 * from PatientHeight 
     where personid= curr.personid 
     and entrydate < curr.entrydate 
     order by entrydate desc) prev 
join 
     PatientWeight wgt 
    on (wgt.entrydate > prev.entrydate or prev.entrydate is null) 
     and wgt.personid = curr.personid 

我的問題的解讀表明,只有 「當前」 數據需要顯示, 「當前」 是

所有條目在PatientWeight的EntryDate落在當前PatientHeight EntryDate和之前的PatientHeight EntryDate