我正在创建存储过程,以基于用户的参数作为过滤器生成报告。我几乎已经可以使用每个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
我不确定这是否只是参数的性质直到某个点才起作用或对子查询不起作用。通过手动编写参数,查询可以完美地工作。不胜感激。
答案 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