sql - 如何优化此 SQL Server 查询 - 多个子查询
问题描述
我在 SQL Server 中有这个带有 4 个子查询的查询,我正在寻找一种优化它的方法:
DECLARE @INICIO DATE
DECLARE @FIN DATE
SET @INICIO='2020-06-17'
SET @FIN='2020-07-27'
SELECT VALO.FECHA_VALORACION,
VALO.CODIGO_PORTAFOLIO,
VALO.CUSIP,
VALO.NUMERO_INVERSION,
VALO.SM_GRUPO
SM_TIPO,
VALO.TIPO_INSTRUMENTO DESCRIPCION_INSTMT,
VALO.CODIGO_MONEDA CODIGO_MONEDA_PAGAR,
VALO.CODIGO_MONEDA CODIGO_MONEDA_RECIBIR,
VALO.ID_CONTRAPARTE,
OP.PRECIO
PRECIO_FX,
VALO.VALOR_NOMINAL,
VALO.VALOR_DERECHO,
VALO.VALOR_OBLIGACION,
VALO.VALOR_UTILIDAD_PERDIDA,
OP.FECHA FECHA_OPERACION,
VALO.TIPO_OPERACION,
OP.VALOR_OPERACION VALOR_OPERACION_COP,
OP.FECHA_VENCIMIENTO,
VALO.SM_GRUPO,
VALO.VALOR_UTILIDAD_PERDIDA_DER,
VALO.VALOR_UTILIDAD_PERDIDA_OBL,
(SELECT SUM(NESTED.VALOR_UTILIDAD_PERDIDA)
FROM Spirit.TSPT_VALORACION_FUT NESTED
WHERE NESTED.CUSIP=VALO.CUSIP
AND NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO
AND FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0)
AND FECHA_VALORACION<=VALO.FECHA_VALORACION
AND VALOR_UTILIDAD_PERDIDA>0
GROUP BY CUSIP,CODIGO_PORTAFOLIO) AS UTILIDAD_MENSUAL,
(SELECT SUM(NESTED.VALOR_UTILIDAD_PERDIDA)
FROM Spirit.TSPT_VALORACION_FUT NESTED
WHERE NESTED.CUSIP=VALO.CUSIP
AND NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO
AND FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0)
AND FECHA_VALORACION<=VALO.FECHA_VALORACION
AND VALOR_UTILIDAD_PERDIDA<0
GROUP BY CUSIP,CODIGO_PORTAFOLIO) AS PERDIDA_MENSUAL,
(SELECT SUM(NESTED.VALOR_UTILIDAD_PERDIDA)
FROM Spirit.TSPT_VALORACION_FUT NESTED
WHERE NESTED.CUSIP=VALO.CUSIP
AND NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO
AND NESTED.FECHA_VALORACION<=VALO.FECHA_VALORACION
AND NESTED.VALOR_UTILIDAD_PERDIDA>0
GROUP BY CUSIP,CODIGO_PORTAFOLIO) AS UTILIDAD_ACUMULADA,
(SELECT SUM(NESTED.VALOR_UTILIDAD_PERDIDA)
FROM Spirit.TSPT_VALORACION_FUT NESTED
WHERE NESTED.CUSIP=VALO.CUSIP
AND NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO
AND FECHA_VALORACION<=VALO.FECHA_VALORACION
AND VALOR_UTILIDAD_PERDIDA<0
GROUP BY CUSIP,CODIGO_PORTAFOLIO) AS PERDIDA_ACUMULADA
FROM Spirit.TSPT_VALORACION_FUT VALO
INNER JOIN Spirit.TSPT_OPERACIONES OP ON OP.NUMERO_INVERSION = VALO.NUMERO_INVERSION
AND OP.TIPO_OPERACION = VALO.TIPO_OPERACION
AND OP.SM_GRUPO IN ('OPTION')
WHERE VALO.SM_GRUPO IN ('OPTION')
AND VALO.CODIGO_PORTAFOLIO IN ('AFP-P','AFP-F')
AND VALO.FECHA_VALORACION >= @INICIO
AND VALO.FECHA_VALORACION <= @FIN
ORDER BY VALO.CUSIP,VALO.FECHA_VALORACION
但我不知道如何整合它并获得最佳效果。太感谢了。
这是先前优化过程的结果。
我一直在尝试这样的一些:
(SELECT sum (case when NESTED.VALOR_UTILIDAD_PERDIDA > 0 then NESTED.VALOR_UTILIDAD_PERDIDA else 0 end) as UTILIDAD_MENSUAL,
sum (case when NESTED.VALOR_UTILIDAD_PERDIDA < 0 then NESTED.VALOR_UTILIDAD_PERDIDA else 0 end) as PERDIDA_MENSUAL
FROM Spirit.TSPT_VALORACION_FUT NESTED
WHERE NESTED.CUSIP=VALO.CUSIP
AND NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO
AND FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0)
AND FECHA_VALORACION<=VALO.FECHA_VALORACION
AND VALOR_UTILIDAD_PERDIDA>0
GROUP BY CUSIP,CODIGO_PORTAFOLIO) AS ACUMULADOS
解决方案
由于您的所有子查询似乎都来自同一个表,您可以将它们合并到FROM
子句中的单个查询中......试试这个......我真的无法调试没有表模式来引用的语法...... .
DECLARE @INICIO DATE
DECLARE @FIN DATE
SET @INICIO='2020-06-17'
SET @FIN='2020-07-27'
SELECT
VALO.FECHA_VALORACION,
VALO.CODIGO_PORTAFOLIO,
VALO.CUSIP,
VALO.NUMERO_INVERSION,
VALO.SM_GRUPO
SM_TIPO,
VALO.TIPO_INSTRUMENTO DESCRIPCION_INSTMT,
VALO.CODIGO_MONEDA CODIGO_MONEDA_PAGAR,
VALO.CODIGO_MONEDA CODIGO_MONEDA_RECIBIR,
VALO.ID_CONTRAPARTE,
OP.PRECIO
PRECIO_FX,
VALO.VALOR_NOMINAL,
VALO.VALOR_DERECHO,
VALO.VALOR_OBLIGACION,
VALO.VALOR_UTILIDAD_PERDIDA,
OP.FECHA FECHA_OPERACION,
VALO.TIPO_OPERACION,
OP.VALOR_OPERACION VALOR_OPERACION_COP,
OP.FECHA_VENCIMIENTO,
VALO.SM_GRUPO,
VALO.VALOR_UTILIDAD_PERDIDA_DER,
VALO.VALOR_UTILIDAD_PERDIDA_OBL,
S.UTILIDAD_MENSUAL,
S.PERDIDA_MENSUAL,
S.UTILIDAD_ACUMULADA,
S.PERDIDA_ACUMULADA
FROM
Spirit.TSPT_VALORACION_FUT VALO
INNER JOIN Spirit.TSPT_OPERACIONES OP ON
OP.NUMERO_INVERSION = VALO.NUMERO_INVERSION
AND OP.TIPO_OPERACION = VALO.TIPO_OPERACION
AND OP.SM_GRUPO IN ('OPTION')
OUTER APPLY (
SELECT
SUM(CASE WHEN FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0) AND VALOR_UTILIDAD_PERDIDA>0
THEN NESTED.VALOR_UTILIDAD_PERDIDA
ELSE 0
END) UTILIDAD_MENSUAL,
SUM(CASE WHEN FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0) AND VALOR_UTILIDAD_PERDIDA<0
THEN NESTED.VALOR_UTILIDAD_PERDIDA
ELSE 0
END) PERDIDA_MENSUAL,
SUM(CASE WHEN NESTED.VALOR_UTILIDAD_PERDIDA>0
THEN NESTED.VALOR_UTILIDAD_PERDIDA
ELSE 0
END) UTILIDAD_ACUMULADA,
SUM(CASE WHEN VALOR_UTILIDAD_PERDIDA<0
THEN NESTED.VALOR_UTILIDAD_PERDIDA
ELSE 0 END
) PERDIDA_ACUMULADA
FROM
Spirit.TSPT_VALORACION_FUT NESTED
WHERE
FECHA_VALORACION<=VALO.FECHA_VALORACION AND
NESTED.CUSIP = VALO.CUSIP AND
NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO
GROUP BY
CUSIP,
CODIGO_PORTAFOLIO
) S
WHERE
VALO.SM_GRUPO IN ('OPTION')
AND VALO.CODIGO_PORTAFOLIO IN ('AFP-P','AFP-F')
AND VALO.FECHA_VALORACION >= @INICIO
AND VALO.FECHA_VALORACION <= @FIN
ORDER BY
VALO.CUSIP,
VALO.FECHA_VALORACION
推荐阅读
- python - 健身房定制环境和 PPO:训练有素的代理总是采取相同的行动,有什么建议吗?
- machine-learning - 以下哪一项是验证学习算法是否正确运行的有用步骤?
- python - Python 更新 json 文件中的字段
- css - 如何使两个响应式流体图像按比例改变它们的大小并始终保持相同的高度?
- mysql - 为什么 MySQL 的“USING”子句的这种用法不正确?
- c - 如何确保将数据写入物理介质?
- security - 如何将 IntelliJ 配置为不是安全问题?
- ios - 如何解决 Swift 警告:“常量‘值’推断为‘AnyClass’类型?(又名'可选
'),这可能是出乎意料的”? - javascript - 使用关键帧对 mouseleave 进行反向淡入淡出效果
- reactjs - (暂停)使用 create-react-app 错误进行 Firebase 托管的原因:1. 未捕获的 SyntaxError: Unexpected token <, 2. 托管 URL 中的白色空白页