我可以在 Redshift 上的存储过程中将两个查询连接在一起吗?
Posted
技术标签:
【中文标题】我可以在 Redshift 上的存储过程中将两个查询连接在一起吗?【英文标题】:Can I join two queries together in a Stored procedure on Redshift? 【发布时间】:2019-07-12 04:45:31 【问题描述】:最初我正在尝试使用函数但无济于事。 Redshift 不允许表返回类型或从表中选择数据。我希望也许有一种方法可以使用存储过程来做到这一点,但我不再有信心了。我为下面列出的代码创建了一个 SP,是否可以为 SP 将两个查询连接到自身?
尝试做一个功能,但不可能发生
YTD current year
select
year
, month
, revenue
,transactiondate
, Flag
from (
select
extract(year from transactiondate) as year
, to_char(transactiondate, 'Mon') as month
, extract(month from transactiondate) as month_number
, sum(netamount) as revenue
,transactiondate
,Flag
from
vw_costs_of_businesss_copy
--where to_date(transactiondate, 'YYYY-MM-DD') <= '2019-06-07' and to_date(transactiondate, 'YYYY-MM-DD') ->= concat(to_char(extract(year from '2019-01-01'), 'YYYY'),'01-01') --Convert the date param to year and concatenate with '01/01'
--where to_date(transactiondate, 'YYYY-MM-DD') <= '2019-06-07' and to_date(concat(to_char(extract(year from to_date('2019-01-01', 'YYYY-MM-DD'))),'01-01') , 'YYYY-MM-DD') >= '2019-01-01' --Convert the date param to year and concatenate with '01/01'
--where to_date(transactiondate, 'YYYY-MM-DD') <= '2019-06-07' and to_date(concat(to_char(Cas(extract(year from to_date('2019-01-01', 'YYYY-MM-DD')) as text ),'-01-01') , 'YYYY-MM-DD') >= '2019-01-01' --Convert the date param to year and concatenate with '01/01'
--where to_date(transactiondate, 'YYYY-MM-DD') <= '2019-06-07' and to_date(concat(to_char(Cast(extract(year from to_date('2019-01-01', 'YYYY-MM-DD')) as Text),'0000'),'-01') , 'YYYY-MM-DD') >= '2019-01-01' --Convert the date param to year and concatenate with '01/01'
where to_date(transactiondate, 'YYYY-MM-DD') <= '2019-06-07' and to_date(transactiondate, 'YYYY-MM-DD')>= to_date(concat(to_char(Cast(extract(year from to_date('2019-01-01', 'YYYY-MM-DD')) as Text),'0000'),'-01') , 'YYYY-MM-DD')
group by
year
, month
, month_number
,transactiondate
, Flag
)
order by month_number, year
--YTD PREV YEAR
select
year
, month
, revenue
,transactiondate
, Flag
from (
select
extract(year from transactiondate) as year
, to_char(transactiondate, 'Mon') as month
, extract(month from transactiondate) as month_number
, sum(netamount) as revenue
,transactiondate
,Flag
from
vw_costs_of_businesss_copy
--where to_date(transactiondate, 'YYYY-MM-DD') <= '2019-06-07' and to_date(transactiondate, 'YYYY-MM-DD') ->= concat(to_char(extract(year from '2019-01-01'), 'YYYY'),'01-01') --Convert the date param to year and concatenate with '01/01'
--where to_date(transactiondate, 'YYYY-MM-DD') <= '2019-06-07' and to_date(concat(to_char(extract(year from to_date('2019-01-01', 'YYYY-MM-DD'))),'01-01') , 'YYYY-MM-DD') >= '2019-01-01' --Convert the date param to year and concatenate with '01/01'
--where to_date(transactiondate, 'YYYY-MM-DD') <= '2019-06-07' and to_date(concat(to_char(Cas(extract(year from to_date('2019-01-01', 'YYYY-MM-DD')) as text ),'-01-01') , 'YYYY-MM-DD') >= '2019-01-01' --Convert the date param to year and concatenate with '01/01'
--where to_date(transactiondate, 'YYYY-MM-DD') <= '2019-06-07' and to_date(concat(to_char(Cast(extract(year from to_date('2019-01-01', 'YYYY-MM-DD')) as Text),'0000'),'-01') , 'YYYY-MM-DD') >= '2019-01-01' --Convert the date param to year and concatenate with '01/01'
where to_date(transactiondate, 'YYYY-MM-DD') <= '2019-06-07' and to_date(transactiondate, 'YYYY-MM-DD')>= to_date(concat(to_char(Cast(extract(year from to_date('2019-01-01', 'YYYY-MM-DD')-1) as Text),'0000'),'-01') , 'YYYY-MM-DD')
group by
year
, month
, month_number
,transactiondate
, Flag
)
order by month_number, year
它需要列出 YTD 和 prev_YTD 以便我可以将其作为参数传递,这可能吗?我意识到我必须为此制作一张桌子。 我在哪里放置 Prev_year、Prev-month 列
【问题讨论】:
【参考方案1】:我认为您正在寻找UNION ALL
的概念来“加入两个查询”。
这是一个使用存储过程的示例。请参阅"Overview of Stored Procedures in Amazon Redshift" 了解更多信息。
CREATE PROCEDURE ytd_comparison(
date_param IN DATE
, result_set INOUT REFCURSOR)
AS $$
BEGIN
OPEN result_set FOR --YTD
SELECT year , month , revenue , transactiondate , Flag
FROM (SELECT EXTRACT(year FROM transactiondate) AS year
, TO_CHAR(transactiondate, 'Mon') AS month
, EXTRACT(month FROM transactiondate) AS month_number
, SUM(netamount) AS revenue
, transactiondate
, Flag
FROM vw_costs_of_businesss_copy
WHERE TO_DATE(transactiondate, 'YYYY-MM-DD') <= date_param
AND TO_DATE(transactiondate, 'YYYY-MM-DD') >= DATE_TRUNC('year',date_param)
GROUP BY year , month , month_number , transactiondate , Flag
)
UNION ALL --YTD PREV YEAR
SELECT year ,month ,revenue ,transactiondate ,Flag
FROM (SELECT EXTRACT(year FROM transactiondate) AS year
, TO_CHAR(transactiondate, 'Mon') AS month
, EXTRACT(month FROM transactiondate) AS month_number
, SUM(netamount) AS revenue
, transactiondate
, Flag
FROM vw_costs_of_businesss_copy
WHERE TO_DATE(transactiondate, 'YYYY-MM-DD') <= DATEADD(year, -1, date_param)
AND TO_DATE(transactiondate, 'YYYY-MM-DD') >= DATE_TRUNC('year', DATEADD(year, -1, date_param))
GROUP BY year , month , month_number , transactiondate , Flag
)
ORDER BY month_number , year
;
RETURN;
END;
$$ LANGUAGE plpgsql;
您需要在调用过程时为输出REFCURSOR
提供名称。您必须使用BEGIN
打开一个事务来维护游标,然后从REFCURSOR
获取输出,然后使用END
事务丢弃结果游标。
BEGIN;
CALL ytd_comparison ('2016-07-01'::DATE, 'ytd_results');
FETCH ALL FROM ytd_results;
END;
更新: 或者,您可以仅创建前一天的视图。
CREATE OR REPLACE VIEW ytd_comparison AS
SELECT year , month , revenue , transactiondate , Flag
FROM (SELECT EXTRACT(year FROM transactiondate) AS year
, TO_CHAR(transactiondate, 'Mon') AS month
, EXTRACT(month FROM transactiondate) AS month_number
, SUM(netamount) AS revenue
, transactiondate
, Flag
FROM vw_costs_of_businesss_copy
WHERE TO_DATE(transactiondate, 'YYYY-MM-DD') <= GETDATE() - 1
AND TO_DATE(transactiondate, 'YYYY-MM-DD') >= DATE_TRUNC('year',GETDATE() - 1)
GROUP BY year , month , month_number , transactiondate , Flag
)
UNION ALL --YTD PREV YEAR
SELECT year ,month ,revenue ,transactiondate ,Flag
FROM (SELECT EXTRACT(year FROM transactiondate) AS year
, TO_CHAR(transactiondate, 'Mon') AS month
, EXTRACT(month FROM transactiondate) AS month_number
, SUM(netamount) AS revenue
, transactiondate
, Flag
FROM vw_costs_of_businesss_copy
WHERE TO_DATE(transactiondate, 'YYYY-MM-DD') <= DATEADD(year, -1, GETDATE() - 1)
AND TO_DATE(transactiondate, 'YYYY-MM-DD') >= DATE_TRUNC('year', DATEADD(year, -1, GETDATE() - 1))
GROUP BY year , month , month_number , transactiondate , Flag
)
ORDER BY month_number , year
;
【讨论】:
从这一点开始的问题是可以把它做成一个视图或表格吗? 要使其成为视图或表格,您必须计算每一天的值,然后在查询时仅过滤您想要的那一天。如果存储过程不合适,使用准备好的语句可能会更好。 docs.aws.amazon.com/redshift/latest/dg/r_PREPARE.html 我只需要它直到今天以及过去两年的年初至今和当月。但是,查看准备语句,我需要传递您重新处理的 SP 给我的结果集中的值。 在这种情况下,是的,你可以很容易地做到这一点。在答案中添加了示例。 老兄你最好的。有时它的蚂蚁小山我们制造了山,但对于我的生活,我可以弄清楚如何做到这一点。真的非常感谢您的帮助!以上是关于我可以在 Redshift 上的存储过程中将两个查询连接在一起吗?的主要内容,如果未能解决你的问题,请参考以下文章