Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql ORACLE:通过一个选择查看不同的日期范围_Sql_Oracle - Fatal编程技术网

Sql ORACLE:通过一个选择查看不同的日期范围

Sql ORACLE:通过一个选择查看不同的日期范围,sql,oracle,Sql,Oracle,我希望能够计算出一年中不同日期的不同年龄段,而不必全部合并 现在的查询如下所示: SELECT to_char(last_day(add_months(sysdate,-1)),'YYYYMM') yrmnth, FLOOR(months_between(last_day(add_months(sysdate,-1)),birth_date)/12), count(distinct id) members from agefile WHERE

我希望能够计算出一年中不同日期的不同年龄段,而不必全部合并

现在的查询如下所示:

   SELECT
      to_char(last_day(add_months(sysdate,-1)),'YYYYMM') yrmnth,
      FLOOR(months_between(last_day(add_months(sysdate,-1)),birth_date)/12),
    count(distinct id) members
    from agefile
    WHERE to_char(from_date, 'YYYYMM')<=to_char(last_day(add_months(sysdate,-1)),'YYYYMM') 
    and to_char(thru_date, 'YYYYMM')>=to_char(last_day(add_months(sysdate,-1)),'YYYYMM')
    GROUP BY to_char(last_day(add_months(sysdate,-1)),'YYYYMM'),
    FLOOR(months_between(last_day(add_months(sysdate,-1)),birth_date)/12)

    UNION ALL

    SELECT
      to_char(last_day(add_months(sysdate,-2)),'YYYYMM') yrmnth,
      FLOOR(months_between(last_day(add_months(sysdate,-2)),birth_date)/12),
    count(distinct id) members
    from agefile
    WHERE to_char(from_date, 'YYYYMM')<=to_char(last_day(add_months(sysdate,-2)),'YYYYMM') 
    and to_char(thru_date, 'YYYYMM')>=to_char(last_day(add_months(sysdate,-2)),'YYYYMM')
    GROUP BY to_char(last_day(add_months(sysdate,-2)),'YYYYMM'),
    FLOOR(months_between(last_day(add_months(sysdate,-2)),birth_date)/12)

    UNION ALL

and so on...
因此,我不希望将agefile传递12次,而是希望传递一次,但输出12倍的ages

例如:

yrmnth age members 201809 1 100 201809 2 120 201809 3 145 201808 1 56 在过去的12个月中,截至每个月的最后一天,有多少会员是x岁,这将是一个商业问题

有没有办法绕过将文件传递12次并使用一个select来执行此操作


谢谢

不要硬编码整数,而是要交叉连接到整数集

你可以这样做:

SELECT ROWNUM as rn FROM agefile
WHERE ROWNUM <= 12

在这种情况下,如果交叉应用于月份列表而不是整数列表,它的清理效果会更好,并且有一个预构建的数字/理货表可以让它更干净。

在with子句中构建月份,并交叉连接表:

with months as
(
  select last_day(add_months(sysdate, -1)) as day from dual
  union all
  select last_day(add_months(sysdate, -2)) as day from dual
  union all
  ...
)
select
  to_char(months.day,'yyyymm') yrmnth,
  floor(months_between(months.day, birth_date) / 12),
  count(distinct id) members
from months cross join agefile
where to_char(from_date, 'yyyymm') <= to_char(months.day, 'yyyymm') 
  and to_char(thru_date, 'yyyymm') >= to_char(months.day, 'yyyymm')
group by
  to_char(months.day, 'yyyymm'),
  floor(months_between(months.day, birth_date) / 12);

您的查询执行了大量冗余操作,可以进行大量清理:

WITH m AS(
  SELECT last_day(add_months(sysdate,level-12)) month_end FROM dual CONNECT BY level <=12
)
SELECT
  m.month_end,
  trunc(months_between(af.birth_date, .month_end)) as age_at,
  count(*) as num_mem
FROM
  age_file af
  CROSS JOIN
  m
GROUP BY
  m.month_end,
  trunc(months_between(af.birth_date, .month_end))
我不太清楚起始日期和截止日期的意义是什么,除非它是活动成员的过滤器,在这种情况下,它可能表示为af.from_日期和af.thru_日期之间的m.month_结束位置

在你的查询中,所有大量的操作日期和炭化都是不必要的——如果你马上要通过只计算一个月的最后一天等方式来减少一天的时间,那么就不需要计算一个月的最后一天

我建议您将日期保留在日期中,因为这更清楚地表明,所表示的年龄是在一个月的最后一天-我认为很多人在查看一个月的日期时默认的假设是,它指的是一个月的开始


目前,此查询还计算当前月份。如果您只希望前12个月不包括当前月份,请在级别查询中选择-13。查询产生1到12,减去12意味着它是-12到0。减去13等于-13到-1

请编辑您的帖子,突出显示您的SQL,然后按{}按钮,m为选择最后一天添加月日期,一级月底从dual CONNECT BY level良好捕获,修复了错误
WITH m AS(
  SELECT last_day(add_months(sysdate,level-12)) month_end FROM dual CONNECT BY level <=12
)
SELECT
  m.month_end,
  trunc(months_between(af.birth_date, .month_end)) as age_at,
  count(*) as num_mem
FROM
  age_file af
  CROSS JOIN
  m
GROUP BY
  m.month_end,
  trunc(months_between(af.birth_date, .month_end))