MS SQL 2005:子查询中的别名问题

MS SQL 2005: Problems with alias in subquery

好的,所以我是一个 SQL 菜鸟,我尝试完成此操作的方法可能不是最好的 - 到目前为止它甚至不起作用,所以这里是:

我有一个 table 的校准数据。设备由序列号(序列号列)标识,每个设备可以有多个由 RunID 标识的校准 运行。有很多不同的东西需要校准,这些值都存储在 CalValue 列中。为了识别哪一行包含什么校准,列 CalID 存在。 我想要得到的是三个不同 CalID 的 CalValue,当它们都不同于某些标准值时。由于一个设备可以有多个 运行,我只对最近的一个感兴趣。

为了说明这一点:

# Serial    #    RunID    #    CalValue   #    CalID    #
#      1    #        0    #    0.5        #        13   #
#      1    #        0    #    0.8        #        24   #
#      1    #        0    #    0.2        #        35   #
#      1    #        1    #    0.5        #        13   #
#      1    #        1    #    0.3        #        24   #
#      1    #        1    #    0.4        #        35   #
#      1    #        2    #    0.0        #        13   #
#      1    #        2    #   -2.3        #        24   #
#      1    #        2    #    0.6        #        35   #
#      2    #        0    #    0.0        #        13   #
#      2    #        0    #    0.0        #        24   #
#      2    #        0    #    0.0        #        35   #
#      2    #        1    #    0.6        #        13   #
#      2    #        1    #    0.7        #        24   #
#      2    #        1    #    0.8        #        35   #
#      2    #        2    #    0.0        #        13   #
#      2    #        2    #    0.0        #        24   #
#      2    #        2    #    0.0        #        35   #

我理想中想要得到的是:

# Serial    #    CalValue.ID=13    #    CalValue.ID=24   #    CalValue.ID=35    #
#      1    #        0.5           #          0.3        #        0.6           #
#      2    #        0.6           #          0.7        #        0.8           #

选择 Serial 1 的值是因为最后所有非默认值都存储在 RunID = 1 行中。连载2也有多个运行,其中第一个和第三个运行只给出了一些标准值,所以选择了第二个运行的值。

所以我想做的是加入 tables,我在这里过滤掉标准值,然后只挑选出具有最高 RunID 的值。我尝试了很多东西,最终 运行 变成了 "The column CalValue was specified multiple times"。我不知道我的解决方案是否真的有效,但这是我的方法:

WITH subq3 AS (
SELECT subq0.Serial AS Serial, subq0.RunID AS RunID, subq0.CalValue AS TRth0, subq1.CalValue AS TRth1, subq2.CalValue AS TRth2 
FROM CalibrationData AS subq0
INNER JOIN CalibrationData AS subq1 ON (subq0.Serial = subq1.Serial AND subq0.RunID = subq1.RunID AND ((subq1.CalID=24) AND (subq1.CalValue<>[=13=].0 And subq1.CalValue<>[=13=].03))) 
INNER JOIN CalibrationData AS subq2 ON (subq0.Serial = subq2.Serial AND subq0.RunID = subq2.RunID AND ((subq2.CalID=35) AND (subq2.CalValue<>[=13=].0)))
WHERE ((subq0.CalID=13) AND (subq0.CalValue<>[=13=].0 And subq0.CalValue<>$-400.0))
)
SELECT t1.Serial, t1.TRth0, t1.TRth1, t1.TRth2
FROM subq3 t1
  LEFT OUTER JOIN subq3 t2
    ON ((t1.Serial = t2.Serial) AND (t1.RunID < t2.RunID))
WHERE t2.Serial IS NULL AND t1.Serial < 90000000
ORDER BY t1.Serial ASC

因为这个问题,我还在 SQLFiddle 中构建了我的示例,并且它的工作方式与我想象的一样。所以我的问题实际上是服务器的特定功能。我们有一个 MS SQL 2005 服务器,它似乎在 subq3 语句中的别名有问题。

有什么可以解决这个问题的建议吗"The column CalValue was specified multiple times"?

更新:添加了业务逻辑

select 
    serial, [13] as [TRth0], [24] as [TRth1],[35] as [TRth2]
from
    (
        select serial,Calvalue,CalID
            from
            (
                select 
                    Serial,
                    Rank() OVER (Partition by Serial order by RunId desc) as rank,
                    calvalue,
                    calid 
                from
                (
                    Select *,count(1) OVER (partition by Serial,runid ) as count from Calibrationdata 
                        where 
                            calValue<>0.00 and 
                                case 
                                    when (calid=13 and calvalue =-400)
                                    or (calid=24 and calvalue =0.03)
                                    then 0 ELSE 1 END =1
                ) d where d.count=3
            ) c
            where c.rank=1
    ) s
PIVOT
( max(calvalue) for calid in ([13],[24],[35])) p

已更新 fiddle link:http://sqlfiddle.com/#!3/c5f52/4

I used rank() in inner query to get only last run's reading for each serial Then I used PIVOT to transform the output.

please try the below query:

select serial, [13] as [TRth0], [24] as [TRth1],[35] as [TRth2]
from
(
  select 
     serial,Calvalue,CalID
  from
     (
      select 
         Serial, 
         Rank() OVER (Partition by Serial order by RunId desc) as rank, 
         calvalue,
         calid
      from Calibrationdata
      ) c
   where c.rank=1
  ) s
PIVOT
 ( 
   max(calvalue) for calid in ([13],[24],[35])
 ) p

sql fiddle link http://sqlfiddle.com/#!3/01c12/7