用户定义的参数不适用于存储过程子查询

时间:2019-04-18 16:29:49

标签: sql sql-server sql-server-2008 stored-procedures parameters

我正在创建存储过程,以基于用户的参数作为过滤器生成报告。我几乎已经可以使用每个SELECT查询,但是最后一个包含一堆LEFT JOIN的查询最终在整个表中返回了NULL

我这样执行存储过程:

exec promediosDot
        @periodo1a = 201612,
        @periodo1b = 201703,
        @periodo2a = 201712,
        @periodo2b = 201803,
        @periodo3a = 201812,
        @periodo3b = 201903,
        @tipGas = 'VENTAS'

这是查询:

CREATE PROCEDURE promediosDot
    @periodo1a INT,
    @periodo1b INT,
    @periodo2a INT,
    @periodo2b INT,
    @periodo3a INT,
    @periodo3b INT,
    @tipGas NVARCHAR(6)
AS
    SELECT DISTINCT 
        T1.HOMOLOG_VP, 
        PROMEDIO1 = ((T2.CANT_PERS1 + T3.CANT_PERS2 + T4.CANT_PERS3 + T5.CANT_PERS4) / 4),
        PROMEDIO2 = ((T6.CANT_PERS1 + T7.CANT_PERS2 + T8.CANT_PERS3 + T9.CANT_PERS4) / 4),
        PROMEDIO3 = ((T10.CANT_PERS1 + T11.CANT_PERS2 + T12.CANT_PERS3 + T13.CANT_PERS4) / 4)
    FROM 
        (SELECT * 
         FROM USOS_CP 
         WHERE PER_PRO > 201611) T1
    LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, 
             COUNT(DISTINCT ID_HR) AS CANT_PERS1 
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo1a 
         GROUP BY 
             HOMOLOG_VP) T2 ON T1.HOMOLOG_VP = T2.HOMOLOG_VP
    LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS2 
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo1a + 1 
         GROUP BY 
             HOMOLOG_VP) T3 ON T1.HOMOLOG_VP = T3.HOMOLOG_VP
    LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS3 
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo1a + 2 
         GROUP BY 
             HOMOLOG_VP) T4 ON T1.HOMOLOG_VP = T4.HOMOLOG_VP
    LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS4 
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo1a + 3 
         GROUP BY 
             HOMOLOG_VP) T5 ON T1.HOMOLOG_VP = T5.HOMOLOG_VP
    --
    LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS1 
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo2a 
         GROUP BY 
             HOMOLOG_VP) T6 ON T1.HOMOLOG_VP = T6.HOMOLOG_VP
    LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS2
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo2a + 1
         GROUP BY 
             HOMOLOG_VP) T7 ON T1.HOMOLOG_VP = T7.HOMOLOG_VP
    LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS3
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo2a + 2
         GROUP BY 
             HOMOLOG_VP) T8 ON T1.HOMOLOG_VP = T8.HOMOLOG_VP
    LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS4
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo2a + 3
         GROUP BY 
             HOMOLOG_VP) T9 ON T1.HOMOLOG_VP = T9.HOMOLOG_VP
    --
    LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS1
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo3a
         GROUP BY 
             HOMOLOG_VP) T10 ON T1.HOMOLOG_VP = T10.HOMOLOG_VP   
     LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS2
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo3a + 1
         GROUP BY 
             HOMOLOG_VP) T11 ON T1.HOMOLOG_VP = T11.HOMOLOG_VP   
    LEFT JOIN 
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS3
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo3a + 2
         GROUP BY 
             HOMOLOG_VP) T12 ON T1.HOMOLOG_VP = T12.HOMOLOG_VP   
    LEFT JOIN
        (SELECT 
             HOMOLOG_VP, COUNT(DISTINCT ID_HR) AS CANT_PERS4
         FROM 
             DOTACION 
         WHERE 
             PERPRO = @periodo3a + 3
         GROUP BY 
             HOMOLOG_VP) T13 ON T1.HOMOLOG_VP = T13.HOMOLOG_VP   
GO

结果(提取):

HOMOLOG_VP  PROMEDIO1   PROMEDIO2   PROMEDIO3
---------------------------------------------
a3          NULL    NULL    NULL
a4          NULL    NULL    NULL

我不确定这是否只是参数的性质直到某个点才起作用或对子查询不起作用。通过手动编写参数,查询可以完美地工作。不胜感激。

2 个答案:

答案 0 :(得分:2)

可能会出现问题,因为您的句点将12月设置为201612,如果将其设置为201613,而不是201701。这是使用整数作为日期值的问题。正如肖恩(Sean)所述,这也可以转换为更简单的查询。

CREATE PROCEDURE promediosDot
        @periodo1a int,
        @periodo1b int,
        @periodo2a int,
        @periodo2b int,
        @periodo3a int,
        @periodo3b int,
        @tipGas nvarchar(6)

AS
SELECT  
    U.HOMOLOG_VP, 
    PROMEDIO1 = (   COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 0, CAST( @periodo1a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END) 
                  + COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 1, CAST( @periodo1a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END)
                  + COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 2, CAST( @periodo1a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END)
                  + COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 3, CAST( @periodo1a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END)) /4,
    PROMEDIO2 = (   COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 0, CAST( @periodo2a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END) 
                  + COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 1, CAST( @periodo2a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END)
                  + COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 2, CAST( @periodo2a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END)
                  + COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 3, CAST( @periodo2a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END)) /4,
    PROMEDIO3 = (   COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 0, CAST( @periodo3a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END) 
                  + COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 1, CAST( @periodo3a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END)
                  + COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 2, CAST( @periodo3a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END)
                  + COUNT(DISTINCT CASE WHEN D.PERPRO = CONVERT( CHAR(6), DATEADD( MM, 3, CAST( @periodo3a AS VARCHAR(8)) + '01'), 112)  THEN D.ID_HR END)) /4
FROM USOS_CP  U
JOIN DOTACION D ON U.HOMOLOG_VP = D.HOMOLOG_VP
WHERE U.PER_PRO > 201611
AND (D.PERPRO BETWEEN @periodo1a AND @periodo1a + 3
    OR D.PERPRO BETWEEN @periodo2a AND @periodo2a + 3
    OR D.PERPRO BETWEEN @periodo3a AND @periodo3a + 3)
GROUP BY U.HOMOLOG_VP
ORDER BY HOMOLOG_VP;

答案 1 :(得分:1)

您发布的代码中没有使用几个参数。但是您可以大大简化该查询。这样的事情应该是同一回事。无需一遍又一遍地加入同一张表。

SELECT cp.HOMOLOG_VP
    , PROMEDIO1 = count(case when d.PERPRO >= @periodo1a and d.PERPRO <= @periodo1a + 3 then 1 end) / 4
    , PROMEDIO2 = count(case when d.PERPRO >= @periodo2a and d.PERPRO <= @periodo2a + 3 then 1 end) / 4
    , PROMEDIO3 = count(case when d.PERPRO >= @periodo3a and d.PERPRO <= @periodo3a + 3 then 1 end) / 4
FROM USOS_CP cp
left join DOTACION d on d.HOMOLOG_VP = cp.HOMOLOG_VP
WHERE cp.PER_PRO > 201611
group by cp.HOMOLOG_VP