SQL实现PriceHistory表当日多行金属价格合并为单行查询
问题原因
你当前写了两个独立的SELECT语句,数据库会将两个语句的结果作为两个独立的结果集返回,因此会得到拆分的两行数据,无法合并为预期的单行结果。另外原语句表名处多写了一组空方括号,属于笔误,会触发对象不存在的报错。
修正方案
使用条件聚合在同一个查询中分别提取黄金、白银对应的开盘价,即可返回单行结果,修正后的完整代码如下:
BEGIN DECLARE @date DATETIME SET @date = CAST(GETDATE() AS DATE) SELECT ISNULL(MAX(CASE WHEN SpotMetal = 'Gold' THEN OpenPrice END), 0) AS GoldSpot, ISNULL(MAX(CASE WHEN SpotMetal = 'Silver' THEN OpenPrice END), 0) AS SilverSpot FROM [dbo].[PriceHistory] WHERE SpotDate = @date AND SpotMetal IN ('Gold','Silver') END
逻辑说明
- 用
CASE表达式仅在金属类型匹配时返回对应开盘价,不匹配时返回NULL - 用
MAX()聚合函数提取对应金属的有效价格:同一日期同一金属仅存在一条价格记录时,聚合操作不会改变价格原值 - 用
ISNULL()将匹配不到数据时的NULL值转换为0,和你原语句的空值处理逻辑完全一致 - 所有逻辑在同一个
SELECT中执行,最终只会返回一行两列的结果,完全符合预期输出要求。
如果偏好关联查询的写法,也可以用子查询交叉连接的方式实现,返回效果一致:
BEGIN DECLARE @date DATETIME SET @date = CAST(GETDATE() AS DATE) SELECT ISNULL(g.OpenPrice, 0) AS GoldSpot, ISNULL(s.OpenPrice, 0) AS SilverSpot FROM (SELECT OpenPrice FROM [dbo].[PriceHistory] WHERE SpotMetal='Gold' AND SpotDate=@date) g CROSS JOIN (SELECT OpenPrice FROM [dbo].[PriceHistory] WHERE SpotMetal='Silver' AND SpotDate=@date) s END
日常使用优先推荐第一种条件聚合的写法,性能更好,语句也更简洁易维护。
内容的提问来源于stack exchange,提问作者user16515314
相关产品推荐
相关产品推荐

