从高度/重量表计算BMI

时间:2011-02-17 20:23:54

标签: sql sql-server

澄清

在完成您的答案并阅读您对此问题的解释后,我需要添加以下内容。

  • 我需要生成整个BMI历史记录,而不是单个值。
  • 两个表中的每个值都需要与另一个表中的相关值配对(如果可能)。

简单问题

在PatientHeight中输入一个条目,计算患者体重中所有条目的BMI(体重指数),其EntryDate介于当前PatientHeight EntryDate和之前的PatientHeight EntryDate之间。除非在PatientWeight中有EntryDates,否则这是真的。那么PatientHeight中的任何EntryDates。在这种情况下,使用最新的PatientHeight条目来计算BMI。

对于PatientHeight中的每个条目,使用PatientWeight中的所有相应值计算BMI(身体质量指数)。

一些逻辑:

  • 在配对时,PatientHeight的EntryDate是< = PatientWeight的EntryDate
  • PatientHeight与PatientWeight有一对多的关系
  • PatientHeight必须考虑先前PatientHeight的EntryDate,并在PatientWeight中匹配EntryDates时将其用作下限。

我有计算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

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分: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

答案 3 :(得分: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之间的所有条目