SQL连接的日期返回多行

问题描述 投票:2回答:2

我想加入2个表。一个具有用于从制造批次,其他限制为所测试的参数的参数测量的数据和日期,所述限制改变。的限制表可以具有应被忽略空白的限制或“0”的限制。我想加入表,因此表明应该被应用到测量极限,即最大parameterlimitdate之前或等于测量日期。我的代码去除日期比测量日期更大的限制,但包括老年限制。感谢所有帮助来审查我的代码,并建议更正。

SELECT data.batch,
       limits.parameter,
       data.measurementdate,
       data.value,
       max(limits.parameterlimitdate) AS limitdate,
       limits.lowerlimit,
       limits.upperlimit,
       CASE
           WHEN (batch.value<limits.lowerlimit
                 OR batch.value>limits.upperlimit) THEN 1
           ELSE 0
       END AS valueoutsidelimits
FROM dbo.limits
LEFT JOIN dbo.data DATA ON limits.parameter = data.parameter
WHERE limits.parameterlimitdate<=batch.measurementdate
  AND NOT (limits.lowerlimit=0
           AND limits.upperlimit=0)
GROUP BY data.batch,
         limits.parameter,
         limits.lowerlimit,
         limits.upperlimit,
         data.value,
         data.measurementdate

日期表:

Batch   Parameter   MeasurementDate Value
A       X           20/02/2018  10.02
A       X           21/02/2018  10.01
B       X           22/02/2018  10.02
C       X           23/02/2018  10.00
D       X           20/02/2018  9.98
E       X           22/02/2018  10.01
A       Y           23/02/2018  6.25
B       Y           22/02/2018  6.31
C       Y           20/02/2018  6.35
A       Z           21/02/2018  220.3

限制表:

    Parameter   ParameterLimitDate  LowerLimit  UpperLimit
    X           18/05/2009          9.98        10.03
    X           01/01/2010          9.98        10.02
    X           02/06/2012      
    X           01/10/2014          0           0
    X           21/02/2018          9.99        10.01
    Y           01/01/2010          6.2         6.3
    Y           05/03/2013          6.3         6.4

所需的输出:

Batch Parameter MeasurementDate Value   LimitDate  LowerLimit UpperLimit ValueOutsideLimits
A     X         20/02/2018      10.02   01/01/2010  9.98      10.02      0
A     X         21/02/2018      10.01   01/01/2010  9.98      10.02      0
B     X         22/02/2018      10.02   21/02/2018  9.99      10.01      1
C     X         23/02/2018      10.00   21/02/2018  9.99      10.01      0
D     X         20/02/2018      9.98    01/01/2010  9.98      10.02      0
E     X         22/02/2018      10.01   21/02/2018  9.99      10.01      0
A     Y         23/02/2018      6.25    05/03/2013  6.3       6.4        1
B     Y         22/02/2018      6.31    05/03/2013  6.3       6.4        0
A     Z         21/02/2018      220.3   



Actual output with duplicate batch parameter measurements:                          
    Batch   Parameter   MeasurementDate Value   LimitDate   LowerLimit  UpperLimit  ValueOutsideLimits
    A   X   20/02/2018  10.02   18/05/2009  9.98    10.03   0
    A   X   20/02/2018  10.02   01/01/2010  9.98    10.02   0
    A   X   21/02/2018  10.01   18/05/2009  9.98    10.03   0
    A   X   21/02/2018  10.01   01/01/2010  9.98    10.02   0
    B   X   22/02/2018  10.02   18/05/2009  9.98    10.03   0
    B   X   22/02/2018  10.02   01/01/2010  9.98    10.02   0
    B   X   22/02/2018  10.02   21/02/2018  9.99    10.01   1
    C   X   23/02/2018  10.00   18/05/2009  9.98    10.03   0
    C   X   23/02/2018  10.00   01/01/2010  9.98    10.02   0
    C   X   23/02/2018  10.00   21/02/2018  9.99    10.01   0
    D   X   20/02/2018  9.98    18/05/2009  9.98    10.03   0
    D   X   20/02/2018  9.98    01/01/2010  9.98    10.02   0
    E   X   22/02/2018  10.01   18/05/2009  9.98    10.03   0
    E   X   22/02/2018  10.01   01/01/2010  9.98    10.02   0
    E   X   22/02/2018  10.01   21/02/2018  9.99    10.01   0
    A   Y   23/02/2018  6.25    01/01/2010  6.2 6.3 0
    A   Y   23/02/2018  6.25    05/03/2013  6.3 6.4 1
    B   Y   22/02/2018  6.31    01/01/2010  6.2 6.3 1
    B   Y   22/02/2018  6.31    05/03/2013  6.3 6.4 0
    A   Z   21/02/2018  220.3
sql sql-server join
2个回答
1
投票

看来你要回到表data的所有记录,由最近的极限数据measurementdate之前有效匹配。在这种情况下,你必须首先从data选择,然后用limits加入。

话虽如此,一个办法来解决这个使用OUTER APPLY

OUTER APPLY (
   SELECT TOP 1 Parameter, ParameterLimitDate, LowerLimit, UpperLimit
   FROM limits
   WHERE limits.parameter = data.parameter AND 
      limits.parameterlimitdate <= data.measurementdate AND
      (COALESCE(limits.lowerlimit, 0) <> 0 AND COALESCE(limits.upperlimit, 0) <> 0)
   ORDER BY limits.parameterlimitdate DESC
) AS limits

而不是LEFT JOIN

因此,实际的查询变为:

SELECT data.batch,
       data.parameter,
       data.measurementdate,
       data.value,
       limits.parameterlimitdate AS limitdate,
       limits.lowerlimit,
       limits.upperlimit,
       CASE
           WHEN (data.value<limits.lowerlimit
                 OR data.value>limits.upperlimit) THEN 1
           ELSE 0
       END AS valueoutsidelimits
FROM dbo.data
OUTER APPLY (
   SELECT TOP 1 Parameter, ParameterLimitDate, LowerLimit, UpperLimit
   FROM limits
   WHERE limits.parameter = data.parameter AND 
      limits.parameterlimitdate <= data.measurementdate AND
      (COALESCE(limits.lowerlimit, 0) <> 0 AND COALESCE(limits.upperlimit, 0) <> 0)
   ORDER BY limits.parameterlimitdate DESC
) AS limits

0
投票

有了您的LEFT JOIN你从限制的所有记录,未通过WHERE子句排除。该日期也未包括在您的GroupBy,所以你得到limits.parameter,limits.lowerlimit和limits.upperlimit的每一个独特的星座的最大日期。

因此,例如一批“A”你得到返回01/01/2010和18/05/2009,因为上限是在该时间内改变。

为了修正它,我建议从批量数据选择并连接经由INNER极限表JOIN如果没有可能性,没有限为可在测量的时间。

© www.soinside.com 2019 - 2024. All rights reserved.