【问题标题】:SQL LISTAGG Min and Max Function IssueSQL LISTAGG 最小和最大函数问题
【发布时间】:2015-05-29 06:32:35
【问题描述】:

需要在列表标签​​中找到最小和最大日期 像这样在一列中 Min Date:01/01/2015 / Max Date:01/05/2015

SELECT D.ITEM_ID AS "ItemId",
       C.NAME AS "ItemName",
       D.UOM_ID AS "UomId",
       B.DESCRIPTION AS "Uom",
       sum(D.REQUIRED_QTY) AS "Quantity",
       LISTAGG(A.REASON, ', ') WITHIN GROUP (ORDER BY A.REASON) "ReasonType",
       LISTAGG(D.REQUIRED_DATE, ', ') WITHIN GROUP (ORDER BY D.REQUIRED_DATE) "PoRequiredDate",  
       LISTAGG(D.PO_COMMENT, ', ') WITHIN GROUP (ORDER BY D.PO_COMMENT) "Comment"
FROM BIZZXE_V2_SCH.REASONS A,
     BIZZXE_V2_SCH.UOMS B,
     BIZZXE_V2_SCH.ITEMS C,
     BIZZXE_V2_SCH.PO_REQUEST_ITEMS D,
     BIZZXE_V2_SCH.PO_REQUESTS E
WHERE E.PO_REQUEST_ID=D.PO_REQUEST_ID
  AND D.ITEM_ID=C.ITEM_ID
  AND D.UOM_ID=B.UOM_ID
  AND D.REASON_ID=A.REASON_ID
GROUP BY D.ITEM_ID, C.NAME, D.UOM_ID, B.DESCRIPTION 

需要将 Min dt 和 Max dt 作为“PoRequiredDate”添加到一列

 WITH DATA AS(
   SELECT  listagg(REQUIRED_DATE, ',') WITHIN GROUP (ORDER BY REQUIRED_DATE) dt
    FROM PO_REQUEST_ITEMS 
  WHERE PO_REQUEST_ID =16

  )
 SELECT dt,
        SUBSTR(dt, 1, instr(dt, ',', 1, 1)-1) min_dt,
         SUBSTR(dt, instr(dt, ',', -1, 1)+1)   max_dt
  FROM data
  /

【问题讨论】:

    标签: sql oracle oracle11g minmax listagg


    【解决方案1】:

    您可以使用语法“KEEP (DENSE_RANK FIRST/LAST...)”来达到您的目的:

       'Min Date: '||min(REQUIRED_DATE) KEEP (DENSE_RANK FIRST ORDER BY REQUIRED_DATE) ||
    ' / Max Date: '||min(REQUIRED_DATE) KEEP (DENSE_RANK LAST ORDER BY REQUIRED_DATE NULLS FIRST)
    

    主要问题是 FIRSTLAST 关键字 - 它们是聚合函数或分析函数。 KEEP 表示将在表达式中使用 FIRST 或 LAST。 DENSE_RANK 表示数据库将仅使用那些具有最小 (FIRST) 或最大 (LAST) 密集等级的值。密集排名计算基于排序,由 ORDER BY 子句设置。

    请注意,在您的情况下,在主表达式中使用 MIN 或 MAX 并不重要。这是因为上述函数“KEEP...DENSE_RANK...FIRST/LAST”仅将那些已经具有极值的记录传递给聚合函数(MIN/MAX)。

    【讨论】:

    • 通过添加“NULLS FIRST”添加了更多详细信息并修复了 NULL 值可能出现的错误。
    【解决方案2】:

    因此,您需要来自 LISTAGG 输出的聚合值的 MINMAX 日期。

    由于 LISTAGG 将始终具有 有序值,因此最小日期将是逗号分隔列表中的 第一个元素,而最大日期将是日期将是每个组中的最后一个元素

    所以,你只需要使用:

    • SUBSTR
    • INSTR

    例如,

    SQL> WITH DATA AS(
      2  SELECT deptno, listagg(hiredate, ',') WITHIN GROUP (ORDER BY deptno) dt
      3    FROM emp
      4   WHERE deptno <> 30
      5  GROUP BY deptno
      6  )
      7  SELECT deptno,
      8         dt,
      9         SUBSTR(dt, 1, instr(dt, ',', 1, 1)-1) min_dt,
     10         SUBSTR(dt, instr(dt, ',', -1, 1)+1)   max_dt
     11  FROM data
     12  /
    
        DEPTNO DT                                                      MIN_DT          MAX_DT
    ---------- ------------------------------------------------------- --------------- ----------
            10 1981-06-09,1981-11-17,1982-01-23                        1981-06-09      1982-01-23
            20 1980-12-17,1981-04-02,1981-12-03,1982-12-09,1983-01-12  1980-12-17      1983-01-12
    
    SQL>
    

    【讨论】:

    • 我需要一列的 Min_Dt 和 Max_Dt
    • @user3359056 然后再上一步,只需在新的 min_dt 和 max_dt 列上应用 MINMAX
    • 我没听懂你说的“然后再走一步,只需在新的 min_dt 和 max_dt 列上应用 MIN 和 MAX。”
    • @user3359056 你能发布一个例子吗?请编辑您的问题并添加输入数据和所需的输出。
    • SELECT LISTAGG('Min Date("' || min(D.REQUIRED_DATE) || '") ' || ',Max Date("' || max(D.REQUIRED_DATE)|| '") ' , ',' ) WITHIN GROUP (ORDER BY D.REQUIRED_DATE) FROM PO_REQUEST_ITEMS D WHERE D.PO_REQUEST_ID=16 ORA-00978: 没有 GROUP BY 的嵌套组函数 此问题与以下查询有关
    猜你喜欢
    • 2012-07-03
    • 2013-12-06
    • 1970-01-01
    • 2016-10-06
    • 2019-08-18
    • 2015-05-07
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多