简体   繁体   English

SQL LISTAGG最小和最大函数问题

[英]SQL LISTAGG Min and Max Function Issue

Need to find min and max date inside of list tag Like this in one column Min Date:01/01/2015 / Max Date:01/05/2015 需要在列表标记中查找最小和最大日期在一列中类似这样最小日期:2015年1月1日/最大日期:2015年1月5日

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 

Need to add Min dt and Max dt to one column as a "PoRequiredDate" 需要将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
  /

So you want the MIN and MAX date from the aggregated values of the LISTAGG output. 因此,您希望使用LISTAGG输出的汇总值中的MINMAX日期。

Since LISTAGG will always have an ordered values , the min date will be the first element in the comma delimited list, and the max date will be the last element in each group . 由于LISTAGG将始终具有有序值 ,因此,最小日期将是逗号分隔列表中的第一个元素 ,而最大日期将是每个组中最后一个元素

So, all you need to use is: 因此,您需要使用的是:

  • SUBSTR SUBSTR
  • INSTR 仪器

For example, 例如,

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>

You could use syntax "KEEP (DENSE_RANK FIRST/LAST...)" for your purpose: 您可以根据需要使用语法“ 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)

The main issues there are FIRST and LAST keywords - they're aggregate or analytic functions. 主要问题是FIRSTLAST关键字-它们是聚合或分析功能。 KEEP indicates that either FIRST or LAST will be used in expression. KEEP表示将在表达式中使用FIRST或LAST。 DENSE_RANK indicates that database will use only those values, which have the minimal (FIRST) or maximal (LAST) dense rank. DENSE_RANK指示数据库将仅使用那些具有最小(FIRST)或最大(LAST)密集等级的值。 Dense rank calculation is based on sorting, which is set by ORDER BY clause. 密集等级计算基于排序,排序由ORDER BY子句设置。

Notice, that in your case it doesn't matter if you use MIN or MAX in main expression. 注意,在您的情况下,在主表达式中使用MIN还是MAX都没有关系。 This is because function "KEEP...DENSE_RANK...FIRST/LAST" described above passes to aggregate function (MIN/MAX) only those records, which already have extreme values. 这是因为上述函数“ KEEP ... DENSE_RANK ... FIRST / LAST”仅将那些已经具有极值的记录传递给聚合函数(MIN / MAX)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM