我有几个表可供选择,我只想选择每个表中相关月份的最后一天的行。这是我到目前为止所做的:
select
crd.indexname,
sum(crd.pct_weight),
extract(year from crd.datadate) as yr,
extract(month from crd.datadate) as mth
from
ref_own.v_msci_issuer_id_map maps,
pm_own.esg_credit_factors msci,
pm_own.pma_sec_attributes_hv sec,
crd_own.ml_corp_index_data_monthly crd
where
maps.msci_issuer_id=msci.issuer_id
and sec.issuer_id=maps.pimco_issuer_id
and extract(year from msci.as_of_date)=extract(year from crd.datadate)
and extract(year from sec.asof_date)=extract(year from crd.datadate)
and extract(month from msci.as_of_date)=extract(month from crd.datadate)
and extract(month from sec.asof_date)=extract(month from crd.datadate)
and crd.isin=sec.isin
and maps.active=1
group by
crd.indexname,
extract(year from crd.datadate) ,
extract(month from crd.datadate)
order by
crd.indexname,
extract(year from crd.datadate) desc ,
extract(month from crd.datadate) desc
我的脚本的问题是一个月内有多个工作日,所以我最终要进行两倍,三倍等的计数。
答案 0 :(得分:1)
此查询将在您的3个表中加入每月的最新可用记录。除非您在3个表之一中有多个 same as_of_date
记录,否则它不会生成重复记录。
它使用JOIN
来生成表关系,并使用关联的请求动态地找到每个表中每个月的最后一条记录。
我添加了一个条件,以过滤crd
中的最后一条记录,如果您在该表中有一个月的多个记录,则该记录不属于您的原始帖子;如果不需要,请删除它。
select
crd.indexname,
count(crd.ISIN),
extract(year from crd.datadate) as yr,
extract(month from crd.datadate) as mth
from
ref_own.v_msci_issuer_id_map maps
join pm_own.esg_credit_factors msci on maps.msci_issuer_id = msci.issuer_id
join pm_own.pma_sec_attributes_hv sec on sec.issuer_id = maps.pimco_issuer_id
join crd_own.ml_corp_index_data_monthly crd on crd.isin = sec.isin
where
maps.active = 1
and msci.as_of_date = (
select max(as_of_date)
from pm_own.esg_credit_factors
where issuer_id = msci.issuer_id and trunc(as_of_date, 'month') = trunc(crd.datadate, 'month')
)
and sec.as_of_date = (
select max(as_of_date)
from pm_own._own.pma_sec_attributes_hv
where issuer_id = sec.issuer_id and trunc(as_of_date, 'month') = trunc(crd.datadate, 'month')
)
and crd.as_of_date = (
select max(as_of_date)
from pm_own._own.pma_sec_attributes_hv
where isin = crd.isin and trunc(as_of_date, 'month') = trunc(crd.datadate, 'month')
)
group by
crd.indexname,
extract(year from crd.datadate) ,
extract(month from crd.datadate)
order by
crd.indexname,
extract(year from crd.datadate) desc ,
extract(month from crd.datadate) desc
答案 1 :(得分:0)
Jumm,也许这样可以更快。如果您使用group by for date代替提取并使用内部联接,我认为您的查询会更快,更优化。要获取一个月的最后一天,可以使用函数LAST_DAY(https://www.techonthenet.com/oracle/functions/last_day.php)并减去日期以获得“每月的最后一天”,并将其包含在where子句中。
select crd.indexname as indexName, count(crd.ISIN) as countISIN, YEAR(crd.datadate) + '-' + MONTH(crd.datadate) as monthYear
from
ref_own.v_msci_issuer_id_map maps INNER JOIN pm_own.esg_credit_factors msci
ON maps.msci_issuer_id=msci.issuer_id
INNER JOIN pm_own.pma_sec_attributes_hv sec
ON sec.issuer_id=maps.pimco_issuer_id
INNER JOIN crd_own.ml_corp_index_data_monthly crd
ON crd.isin=sec.isin
where msci.as_of_date = (SELECT MAX(as_of_date) FROM msci group by (msci.as_of_date - LAST_DAY(crd.datadate)) LIMIT 1)
and sec.as_of_date = (SELECT MAX(as_of_date) FROM sec group by (msci.as_of_date - LAST_DAY(crd.datadate)) LIMIT 1)
and maps.active=1
group by crd.indexname,crd.datadate
order by crd.indexname, crd.datadate desc
答案 2 :(得分:0)
您可以使用LAST_DAY()来计算每个月的结束日期,强烈建议您不要在表名之间使用逗号,因为25年前“显式连接语法”已正式化。
SELECT
crd.indexname
, extract(year from crd.datadate) as yr
, extract(month from crd.datadate) as mth
, COUNT( crd.ISIN )
FROM ref_own.v_msci_issuer_id_map maps
INNER JOIN pm_own.esg_credit_factors msci ON maps.msci_issuer_id = msci.issuer_id
INNER JOIN pm_own.pma_sec_attributes_hv sec ON sec.issuer_id = maps.pimco_issuer_id AND sec.asof_date = msci.as_of_date
INNER JOIN crd_own.ml_corp_index_data_monthly crd ON crd.isin = sec.isin
WHERE maps.active = 1
AND msci.as_of_date = last_day(msci.as_of_date)
GROUP BY
crd.indexname
, extract(year from crd.datadate)
, extract(month from crd.datadate)
ORDER BY
crd.indexname
, extract(year from crd.datadate) DESC
, extract(month from crd.datadate) DESC
答案 3 :(得分:0)
使用RANK
分析函数,您不需要使用任何相关的子查询:
SELECT indexname,
SUM(pct_weight),
EXTRACT(year FROM datadate) AS yr,
EXTRACT(month FROM datadate) AS mth
FROM (
SELECT crd.indexname,
crd.pct_weight,
TRUNC( crd.datadate, 'MM' ) AS datadate,
RANK() OVER (
PARTITION BY crd.indexname, TRUNC( crd.datadate, 'MM' )
ORDER BY TRUNC( crd.datadate, 'DD' ) DESC
) AS rnk
FROM ref_own.v_msci_issuer_id_map maps
INNER JOIN pm_own.esg_credit_factors msci
ON ( maps.msci_issuer_id=msci.issuer_id )
INNER JOIN pm_own.pma_sec_attributes_hv sec
ON ( sec.issuer_id=maps.pimco_issuer_id )
INNER JOIN crd_own.ml_corp_index_data_monthly crd
ON ( TRUNC( msci.as_of_date, 'MM' ) = TRUNC( crd.datadate )
AND TRUNC( sec.asof_date, 'MM' ) = TRUNC( crd.datadate )
AND crd.isin=sec.isin )
WHERE maps.active=1
)
WHERE rnk = 1
GROUP BY
indexname,
EXTRACT(year FROM datadate) ,
EXTRACT(month FROM datadate)
order by
indexname,
EXTRACT(year FROM datadate) DESC,
EXTRACT(month FROM datadate) DESC