【问题标题】:In Oracle How do we get multiple columns in result which are not in tables在Oracle中,我们如何在结果中获得不在表中的多个列
【发布时间】:2021-10-26 07:38:43
【问题描述】:

例如:

我有一个名为 "T1"

的表格

我需要这样的结果:

如果 "earlist_run_date" , "last_rundate" & "remainng_run_dates" 在表中 T1 可能有使用 PIVOT

但我不知道如何将这 3 列带入结果集中。任何解决方案将不胜感激

【问题讨论】:

  • “remaining_run_dates”是什么意思?在您的表格中,这些日期不是“剩余的”。这些日期的目的是什么?我什至无法想象为什么需要这些信息(您的查询更复杂)。
  • remaining_run_dates 是特定 job_id 的第一次运行和最后一次运行之间的日期。我收到了这个问题形式的采访。
  • 是的,是的……我明白……但是为什么需要它们呢?你不能从最早/最后的字段中推断出它们吗?如果您希望在该列 730 日期中的最早日期和最后日期之间有 2 年?
  • @jaime-drq 你说得对,我认为那是一个,但即使我可以删除“remaining_run_dates”,我将如何在结果中带来其他两列
  • 如果删除该列,查询会非常简单,我会在答案中显示

标签: sql oracle pivot oracle19c


【解决方案1】:

我猜你想要这样的东西。可能有更好的方法来消除 listagg 中的第一行和最后一行,我没有想到,但这应该是相当有效的。

with ranked_t1 as (
  select t1.*,
         rank() over( partition by job_id
                          order by run_date asc ) asc_rank,
         rank() over( partition by job_id
                          order by run_date desc ) desc_rank
    from t1
)
select job_id,
       min( run_date ) earliest_run_date,
       max( run_date ) last_rundate,
       listagg( (case when asc_rank != 1
                       and desc_rank != 1
                      then run_date
                      else null
                   end), ' ' )
         within group( order by run_date ) remaining_run_dates
  from ranked_t1
 group by job_id;

【讨论】:

  • 希望你能在他工作一年多的时候支持他。很高兴让我的工作得到支持这个答案的人......
  • @JaimeDrq - 当然,如果您希望报告将一千个日期连接在一起,您需要使用返回clob 而不是listagg 的用户定义聚合。如果job_id 可以有两次相同的run_date,您需要讨论要求以及是否使用row_numberdense_rank 而不是rank。询问业务用户为什么他们想要这样的东西以及是否有更好的方法可以让他们获得他们想要的信息当然是合理的。
  • 谢谢@JustinCave,至少有人会思考让我感觉很好
【解决方案2】:

删除remaining_run_dates 列,您会得到一个简单的查询

select 
  JOB_ID, 
  min(RUN_DATE) as earliest_run_date,
  max(RUN_DATE) as last_rundate
from T1
group by JOB_ID

【讨论】:

  • 是的,但是remaining_run_dates 是一个指定要求,所以我们不能直接放弃它。
  • 问题清楚地表明“我需要这样的结果”,并显示带有剩余运行日期列表的报告图像。您是否认为此要求荒谬是您的事,但报告包含串联的值字符串并不罕见(这就是 Oracle 为我们提供 listagg() 函数的原因)。至于我是谁,如果你真的有兴趣,可以点击我的个人资料。
  • 如果你想知道,我告诉你。 listagg() 的最大大小为 4000 个字符。因此,如果我们以最小表达式 (yyyymmdd) 理解日期,我们就有 500 个日期的空间。您还在认为这是一个好的解决方案吗?
  • 因为 Oracle 12.2 listagg() 支持 ON OVERFLOW 子句来处理这种情况。在此之前,是的,我们必须明确应用 substr() 来处理潜在的溢出。除此之外,我倾向于发现用户对他们的要求被视为“愚蠢”而感到不满。我认为讨论限制和解决方法,并确定我们可以实施什么来满足他们的需求会更有成效。但是,如果您的方法对您有用,那就没问题了。
  • @APC 现在我们开始理解我们了...对不起,如果我很粗鲁,但仅仅因为“他们告诉我”而做事让我很生气。我认为 IT 人员的强项之一是引导用户了解他/她想要什么。在这种情况下,对我来说,拥有一个包含大量日期的列是没有用的,并且可能有更好的方法来解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-18
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
相关资源
最近更新 更多