好的,所以我是SQL菜鸟,而我试图完成这项工作的方式可能不是最好的 - 而且到目前为止它还没有工作,所以这里有:< / p>
我所拥有的是一张充满校准数据的表格。设备由序列号(列串行)标识,每个设备可以具有由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行中。 Serial 2也有多次运行,其中第一次和第三次运行只给出了一些标准值,因此选择了第二次运行的值。
所以我尝试做的是连接表,我过滤掉标准值,然后只选择具有最高RunID的值。我已经尝试了多项内容,最终进入了&#34;列CalValue被多次指定&#34;。如果我的解决方案实际上不起作用,我没有真正的线索,但这是我的方法:
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<>$0.0 And subq1.CalValue<>$0.03)))
INNER JOIN CalibrationData AS subq2 ON (subq0.Serial = subq2.Serial AND subq0.RunID = subq2.RunID AND ((subq2.CalID=35) AND (subq2.CalValue<>$0.0)))
WHERE ((subq0.CalID=13) AND (subq0.CalValue<>$0.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 Server,它似乎在subq3
语句中的别名有问题。
任何建议我如何解决这个问题&#34; CalValue列被多次指定&#34;?
答案 0 :(得分:1)
更新:添加了业务逻辑
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
更新了小提琴链接:http://sqlfiddle.com/#!3/c5f52/4
我在内部查询中使用了
rank()
来获取每个serial
的最后一次阅读 然后我使用PIVOT
来转换输出。请尝试以下查询:
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