Sql 提取日期字段
我需要从第一个表中提取month字段,我希望结果看起来像第二个表 我知道使用EXTRACTMONTH FROM BEGIN_DATE获取月份,但我不确定如何显示所有日期字段。有什么想法吗?使用oraclesqlSql 提取日期字段,sql,oracle,date,Sql,Oracle,Date,我需要从第一个表中提取month字段,我希望结果看起来像第二个表 我知道使用EXTRACTMONTH FROM BEGIN_DATE获取月份,但我不确定如何显示所有日期字段。有什么想法吗?使用oraclesql 我想我终于明白你想要什么了;您正在运行查询的是SYSDATE。基于此,您希望为每个人的ID获取开始日期和系统日期之间的所有月份 如果是这样,给你: SQL> with test (person_id, begin_date) as 2 (select 123, date
我想我终于明白你想要什么了;您正在运行查询的是SYSDATE。基于此,您希望为每个人的ID获取开始日期和系统日期之间的所有月份 如果是这样,给你:
SQL> with test (person_id, begin_date) as
2 (select 123, date '2017-11-01' from dual union
3 select 654, date '2017-09-01' from dual
4 )
5 select person_id,
6 to_char(add_months(trunc(begin_date, 'mm'), column_value - 1), 'mm') mon
7 from test,
8 table(cast(multiset
9 (select level lvl from dual
10 connect by level <= round(months_Between (sysdate, begin_date)) + 1)
11 as sys.odcinumberlist))
12 order by 1, 2;
PERSON_ID MO
---------- --
123 01
123 11
123 12
654 01
654 09
654 10
654 11
654 12
8 rows selected.
SQL>
这里有一种方法可以做到这一点。请注意,我将列名从Month改为mth Month是Oracle关键字,它不应用作表名或列名。我还显示了完整的月份描述,也就是说,包括年份,以便在同一月份(例如,同一个人的id不止一次)时不会出现混淆。通过将格式模型调整为_CHAR,您可以将其更改为仅显示月份,但这对我来说没有多大意义 测试数据位于WITH子句中,该子句不是SQL查询的一部分;删除它,并在SELECT查询中使用实际的表名,而不是我在WITH子句中创建的虚构名称
with
inputs ( person_id, begin_date, end_date ) as (
select 123, date '2017-11-01', date '2199-12-31' from dual union all
select 654, date '2017-09-01', date '2017-10-31' from dual union all
select 789, date '2017-12-01', date '2199-12-31' from dual
)
select person_id,
to_char(add_months(trunc(begin_date, 'mm'), level - 1), 'mm-yyyy') as mth,
case when add_months(trunc(begin_date, 'mm'), level - 1) <= end_date
then 'Y' else 'N' end as yn
from inputs
connect by add_months(trunc(begin_date, 'mm'), level - 1) <= sysdate
and prior person_id = person_id
and prior sys_guid() is not null
order by person_id, level
;
PERSON_ID MTH YN
---------- ------- --
123 11-2017 Y
123 12-2017 Y
123 01-2018 Y
654 09-2017 Y
654 10-2017 Y
654 11-2017 N
654 12-2017 N
654 01-2018 N
789 12-2017 Y
789 01-2018 Y
10 rows selected
还有一件事-在示例数据中,您的开始日期始终是一个月的开始。如果这是有保证的,那么您可以简化代码-不需要trunc…,“mm”-但我仍然不会更改它;您不知道该列的这个特殊属性将来是否会继续存在,如果它发生了变化,您会很高兴代码已经解决了它。mathguy答案的变体:
SELECT
person_id
, TO_CHAR(ADD_MONTHS(begin_date, LEVEL-1), 'mm') m
, TO_CHAR(ADD_MONTHS(begin_date, LEVEL-1), 'yyyy') y
, CASE WHEN ADD_MONTHS(begin_date, LEVEL-1) BETWEEN begin_date and end_date THEN 'Y' ELSE 'N' END AS yn
FROM
person_table
CONNECT BY
LEVEL <= MONTHS_BETWEEN(TRUNC(SYSDATE, 'MON'), TRUNC(begin_date, 'MON')) + 1
AND prior person_id = person_id
AND prior sys_guid() IS NOT NULL
ORDER BY
person_id, y, m;
仅供参考。我不确定如何。。。从开始日期算起的一个月是否有效?我不确定结束日期是否正确;真的是2199吗?看起来您希望在第二个表中创建尽可能多的行,因为在开始日期和结束日期之间有个月,但是-如果年份相差那么大,则不清楚您真正想要做什么。当person 654仅显示9/1和10/31时,我如何从person 654中提取所有月份?是的,今年的截止日期实际上是2199年。这一年是为了表明他们仍然活跃。我不明白你怎么称呼654人的所有月份。有9月1日和10月31日。那么,如何从这些值中得到第9、10、11、12、1个月?要使用的算法是什么?如果我今天跑步,我将如何获得所有这些月?