此存储过程在SQL Server 2017中显示子查询错误

问题描述 投票:-1回答:2
ALTER PROCEDURE daily_routine
AS
BEGIN
    INSERT INTO temp_stats (i_count, r_count, s_count, w_count, n_count, z_count, t_count, 
                            p_hour, p_location, p_location_count, 
                            p_location_percentage, p_hour_percentage, d_date)
    VALUES (
       (SELECT SUM(i_count) as i_count FROM temp_h_stats),
       (SELECT SUM(r_count) as r_count FROM temp_h_stats),
       (SELECT SUM(s_count) as s_count FROM temp_h_stats),
       (SELECT SUM(w_count) as w_count FROM temp_h_stats),
       (SELECT SUM(n_count) as n_count FROM temp_h_stats),
       (SELECT SUM(z_count) as z_count FROM temp_h_stats),
       (SELECT SUM(t_count) as t_count FROM temp_h_stats),
       (SELECT time_range AS p_hour FROM temp_h_stats 
        WHERE t_count = (SELECT MAX(t_count) FROM temp_h_stats)),
       (SELECT p_location AS p_location FROM temp_hourly_stats 
        WHERE t_count = (SELECT MAX(t_count) FROM temp_hourly_stats)),
       (SELECT p_location_count AS p_location_count FROM temp_h_stats 
        WHERE p_location_count = (SELECT MAX(p_location_count) FROM temp_h_stats)),
       (SELECT MAX(p_location_percentage) AS p_location_percentage FROM temp_h_stats),
       (SELECT (MAX(t_count) * 100) / SUM(t_count) AS p_hour_percentage FROM temp_h_stats),
       (SELECT DATEADD(DD, -1,CURRENT_TIMESTAMP) AS recorded_date))
END

此查询的输出是错误:

子查询返回了多个值。当子查询遵循=,!=,,> =或将子查询用作表达式时,不允许这样做。

而且我还用相同的查询在SQL Server 2017中实现了与该过程相同的过程,只是表名不同,并且可以正常工作,但我不知道为什么此过程不起作用。

sql sql-server stored-procedures subquery sql-server-2017
2个回答
0
投票

这样的东西应该更好:

ALTER Procedure daily_routine
AS
BEGIN


DECLARE @MaxCounT_h_stats BIGINT
       ,@MaxCounT_hourly_states BIGINT
       ,@MaxLocation_Count BIGINT;

SET @MaxCounT_h_stats = (select max(t_count) from temp_h_stats);
SET @MaxCounT_hourly_states = (select max(t_count) from temp_hourly_stats);
SET @MaxLocation_Count = (select max(p_location_count) from temp_h_stats);

INSERT INTO temp_stats(i_count,r_count,s_count,w_count,n_count,z_count,t_count,p_hour,p_location,p_location_count,p_location_percentage,p_hour_percentage,d_date)
SELECT SUM(i_count) as i_count
      ,SUM(r_count) as r_count
      ,SUM(s_count) as s_count
      ,SUM(w_count) as w_count
      ,SUM(n_count) as n_count
      ,SUM(z_count) as z_count
      ,SUM(t_count) as t_count
      ,MAX(IIF(t_count = @MaxCounT_h_stats, time_range, NULL) as p_hour
      ,MAX(IIF(t_count = @MaxCounT_hourly_states, p_location, NULL) as p_location
      ,MAX(IIF(p_location_count = @MaxLocation_Count, p_location_count, NULL) as p_location_count
      ,MAX(p_location_percentage) as p_location_percentage
      ,(MAX(t_count)*100)/SUM(t_count) as p_hour_percentage
      ,DATEADD(DD, -1,CURRENT_TIMESTAMP) as recorded_date)
FROM temp_h_stats

END

您的主要问题是您使用了过多的子查询,以防一次读取一张表就可以这样做。其中之一:

(SELECT time_range as p_hour from temp_h_stats where t_count= (select max(t_count) from temp_h_stats)),
(SELECT p_location as p_location from temp_hourly_stats where t_count= (select max(t_count) from temp_hourly_stats)),
(SELECT p_location_count as p_location_count from temp_h_stats where p_location_count = (select max(p_location_count) from temp_h_stats)),

返回更多的一个值,因此您将收到此错误。如果您不喜欢使用我的版本,只需在上述语句上添加一个聚合函数即可。


0
投票

您的问题显然是正在获得最大值的子查询正在返回多个值。

以下代码假定temp_hourly_stats确实是temp_h_stats。该代码可以轻松调整为处理两个不同的表,但是名称看起来非常相似。

我建议使用单个查询和窗口函数:

INSERT INTO temp_stats (i_count, r_count, s_count, w_count, n_count, z_count, t_count ,p_hour, p_location, p_location_count, p_location_percentage, p_hour_percentage, d_date)
    SELECT SUM(i_count) as i_count,
           SUM(r_count) as r_count,
           SUM(s_count) as s_count,
           SUM(w_count) as w_count,
           SUM(n_count) as n_count,
           SUM(z_count) as z_count
           SUM(t_count) as t_count,
           MAX(CASE WHEN seqnum_t_count = 1 THEN time_range END) as p_hour,
           MAX(CASE WHEN seqnum_t_count = 1 THEN p_location END) as p_location
           MAX(p_location_count) as p_location_count
           MAX(p_location_percentage) as p_location_percentage
           (MAX(t_count) * 100) / SUM(t_count) as p_hour_percentage
           DATEADD(day, -1, CURRENT_TIMESTAMP) as recorded_date)
    FROM (SELECT ths.*,
                 ROW_NUMBER() OVER (ORDER BY t_count DESC) as seqnum_t_count
          FROM temp_h_stats ths
         ) t;

请注意,我已经简化了此逻辑:

  (SELECT p_location_count AS p_location_count
   FROM temp_h_stats 
   WHERE p_location_count = (SELECT MAX(p_location_count) FROM temp_h_stats)
  ),

收件人:

MAX(p_location_count)
© www.soinside.com 2019 - 2024. All rights reserved.