什么是多次重复使用同一查询的替代方法。我想将查询存储在某个地方,并在需要时调用它。 我正在计算4个公式:MTD销售量,MTD上一年的销售量,MAT的销售量,MAT的上一年的销售量,分别作为5种不同产品的列:A,B,C,D,E。以及一些静态条件(例如帐户详细信息和直接销售),应该提供
我要查询Case语句4次(对于公式)* 5次(对于产品),以为所有5个产品定义具有静态条件的公式。即我的查询中几乎有80%重复了4 * 5 = 20次。没有比这20次重复80%的查询的方法了,还有什么更好的办法了。请注意,我不必将查询的值存储为函数,而是可以存储查询的重复部分并在需要的地方调用它?
代码:
SELECT A1.*,
-- MTD FOR PRODUCTS A,B,C,D
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='A'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=EXTRACT(YEAR FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A)))
THEN SALES ELSE 0 END AS MTD_PRODUCT_A,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='B'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=EXTRACT(YEAR FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A)))
THEN SALES ELSE 0 END AS MTD_PRODUCT_B,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='C'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=EXTRACT(YEAR FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A)))
THEN SALES ELSE 0 END AS MTD_PRODUCT_C,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='D'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=EXTRACT(YEAR FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A)))
THEN SALES ELSE 0 END AS MTD_PRODUCT_D,
---MTD LAST YEAR FOR PRODUCTS A,B,C,D
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='A'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=(SELECT EXTRACT(YEAR FROM MAX(SHOWN_DATE))-1 FROM TABLE_A))
THEN SALES ELSE 0 END AS MTD_PY_PRODUCT_A,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='B'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=(SELECT EXTRACT(YEAR FROM MAX(SHOWN_DATE))-1 FROM TABLE_A))
THEN SALES ELSE 0 END AS MTD_PY_PRODUCT_B,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='C'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=(SELECT EXTRACT(YEAR FROM MAX(SHOWN_DATE))-1 FROM TABLE_A))
THEN SALES ELSE 0 END AS MTD_PY_PRODUCT_C,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='D'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=(SELECT EXTRACT(YEAR FROM MAX(SHOWN_DATE))-1 FROM TABLE_A))
THEN SALES ELSE 0 END AS MTD_PY_PRODUCT_D,
----MAT SALES FOR PRODUCT A,B,C,D
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='A'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-11)
and
trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'))
THEN SALES ELSE 0 END AS MAT_PRODUCT_A,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='B'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-11)
and
trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'))
THEN SALES ELSE 0 END AS MAT_PRODUCT_B,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='C'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-11)
and
trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'))
THEN SALES ELSE 0 END AS MAT_PRODUCT_C,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='D'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-11)
and
trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'))
THEN SALES ELSE 0 END AS MAT_PRODUCT_D,
---MAT LAST YEAR SALES FOR PRODUCTS A,B,C,D
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='A'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-23)
and
add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-12))
THEN SALES ELSE 0 END AS MAT_PRODUCT_A,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='B'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-23)
and
add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-12))
THEN SALES ELSE 0 END AS MAT_PRODUCT_B,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='C'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-23)
and
add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-12))
THEN SALES ELSE 0 END AS MAT_PRODUCT_C,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='D'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-23)
and
add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-12))
THEN SALES ELSE 0 END AS MAT_PRODUCT_D
FROM TABLE_A A1
答案 0 :(得分:1)
有几种选择。
如果仅需要定期创建基础数据(例如,每天一次或每周一次),则可以安排作业并创建表。这可能是跨不同数据库处理复杂查询的最常见解决方案。
如果查询本身不是特别复杂,或者每次都需要最新数据,则使用(常规)视图。这是封装查询的内置功能。</ p>
另一个选择是实例化视图。这些就像表一样,因为不需要(显式)重新计算数据。这些就像视图一样,因为数据是最新的。您可以在documentation中进一步了解它们。
答案 1 :(得分:0)
使用分析函数查找最大日期值:
SELECT A1.*,
CASE
WHEN ACCOUNT<> 'Not Provided'
AND TYPE<> 'DIRECT'
AND PRODUCT='A'
AND date_month_trunc = max_date_month
THEN SALES
ELSE 0
END AS MTD_PRODUCT_A,
/* B, C, D */
CASE
WHEN ACCOUNT <> 'Not Provided'
AND TYPE<> 'DIRECT'
AND PRODUCT='A'
AND date_month_trunc = max_date_month - INTERVAL '1' YEAR
THEN SALES
ELSE 0
END AS MTD_PY_PRODUCT_A,
/* B, C, D */
CASE
WHEN ACCOUNT<> 'Not Provided'
AND TYPE<> 'DIRECT'
AND PRODUCT='A'
AND date_month BETWEEN ADD_MONTHS( max_date_month - 11 ) AND max_date_month
THEN SALES
ELSE 0
END AS MAT_PRODUCT_A,
/* B, C, D */
CASE
WHEN ACCOUNT<> 'Not Provided'
AND TYPE<> 'DIRECT'
AND PRODUCT='A'
AND date_month BETWEEN ADD_MONTHS( max_date_month, -23 ) AND ADD_MONTHS( max_date_month, -12 )
THEN SALES
ELSE 0
END AS MAT_PRODUCT_A
/* B, C, D */
FROM (
SELECT a.*,
TRUNC( date_month, 'MM' ) AS date_month_trunc,
MAX( TRUNC( date_month, 'MM' ) ) OVER () AS max_date_month
FROM TABLE_A a
) A1
您可以通过将CASE
的公共元素移到子查询来使其更短:
SELECT A1.*,
CASE
WHEN PRODUCT='A'
AND date_month_trunc = max_date_month
THEN not_provided_direct_sales
ELSE 0
END AS MTD_PRODUCT_A,
/* B, C, D */
CASE
WHEN PRODUCT='A'
AND date_month_trunc = max_date_month - INTERVAL '1' YEAR
THEN not_provided_direct_sales
ELSE 0
END AS MTD_PY_PRODUCT_A,
/* B, C, D */
CASE
WHEN PRODUCT='A'
AND date_month BETWEEN ADD_MONTHS( max_date_month - 11 ) AND max_date_month
THEN not_provided_direct_sales
ELSE 0
END AS MAT_PRODUCT_A,
/* B, C, D */
CASE
WHEN PRODUCT='A'
AND date_month BETWEEN ADD_MONTHS( max_date_month, -23 ) AND ADD_MONTHS( max_date_month, -12 )
THEN not_provided_direct_sales
ELSE 0
END AS MAT_PRODUCT_A
/* B, C, D */
FROM (
SELECT a.*,
CASE
WHEN ACCOUNT<> 'Not Provided'
AND TYPE<> 'DIRECT'
THEN SALES
ELSE 0
END AS not_provided_direct_sales,
TRUNC( date_month, 'MM' ) AS date_month_trunc,
MAX( TRUNC( date_month, 'MM' ) ) OVER () AS max_date_month
FROM TABLE_A a
) A1
答案 2 :(得分:-1)
您可以创建一个临时表,然后使用exec关键字
调用存储过程以填充临时表。