2

是否可以在 listagg 函数中没有 order by 子句?我应该这样做以保留值的顺序。顺便说一句,我正在使用 oracle 11g。以下是我正在使用的查询:

SELECT 
      wipData."Transaction Type"
      ,wipData."Details"
      ,wipData."Values"
      ,NULL
      ,wipdata.containerid
      ,wipdata.specid
      ,wipdata.wiptrackinggroupkeyid
      ,wipdata.wiplothistoryid
      ,NULL wipdatasetupid
      ,wipdata.specname
      ,NULL linkid
FROM
(
    SELECT wipdata.containerid
          ,wipdata.wiplothistoryid
          ,wipdata.wiptrackinggroupkeyid
          ,wipdata.specid  
          ,wipdata.specname
          ,'WIP Data Collection @'|| SUBSTR(wipdata.specname,0,4) AS "Transaction Type"
          ,LISTAGG(wipdata.wipdatanamename ||': ' , 'break') WITHIN GROUP ( ORDER BY wipdata.wipdatanamename) AS "Details" 
          ,LISTAGG(wipdata.wipdatavalue, 'break') WITHIN GROUP ( ORDER BY wipdata.wipdatanamename) AS "Values" 
    FROM
    (
      SELECT c.containerid
            ,wldd.wipdatanamename
            ,wldd.wipdatavalue
            ,wldd.iswaferdata
            ,wl.specname
            ,wl.wiplothistoryid
            ,wl.wiptrackinggroupkeyid
            ,wl.specid
      FROM Container C
      JOIN a_wiplothistory wl ON c.containerid = wl.containerid
      JOIN a_wiplotdetailshistory wld ON wl.wiplothistoryid = wld.wiplothistoryid
      JOIN a_wiplotdetailsdatahistory wldd ON wld.wiplotdetailshistoryid = wldd.wiplotdetailshistoryid
      WHERE c.containername = :lotID AND wldd.iswaferdata = 0 AND wldd.servicename <> 'AdHocWIPData'
    ) wipdata
    GROUP BY wipdata.containerid
          ,wipdata.wiplothistoryid
          ,wipdata.wiptrackinggroupkeyid
          ,wipdata.specid  
          ,wipdata.specname

) WipData

UNION ALL

SELECT 
      wipData."Transaction Type"
      ,wipData."Details"
      ,wipData."Values"
      ,NULL
      ,wipdata.containerid
      ,wipdata.specid
      ,wipdata.wiptrackinggroupkeyid
      ,wipdata.wiplotid
      ,NULL
      ,wipdata.specname
      ,NULL
FROM
(
SELECT wipdata.containerid
      ,wipdata.wiplotid
      ,wipdata.wiptrackinggroupkeyid
      ,wipdata.specid  
      ,wipdata.specname
      ,'WIP Data Collection @'|| SUBSTR(wipdata.specname,0,4) AS "Transaction Type"
      ,LISTAGG(wipdata.wipdatanamename ||': ' || wipdata.wipdatavalue, 'break') WITHIN GROUP ( ORDER BY wipdata.wipdatanamename) AS "Details" 
      ,LISTAGG(wipdata.wipdatavalue, 'break') WITHIN GROUP ( ORDER BY wipdata.wipdatanamename) AS "Values" 
FROM
(
  SELECT c.containerid
        ,wldd.wipdatanamename
        ,wldd.wipdatavalue
        ,wldd.iswaferdata
        ,wl.specname
        ,wl.wiplotid

        ,wl.wiptrackinggroupkeyid
        ,wl.specid
  FROM Container C
  JOIN a_wiplot wl ON c.containerid = wl.containerid
  JOIN a_wiplotdetails wld ON wl.wiplotid = wld.wiplotid
  JOIN a_wiplotdetailsdata wldd ON wld.wiplotdetailsid = wldd.wiplotdetailsid
  WHERE c.containername = :lotID AND wldd.iswaferdata = 0 AND wldd.servicename <> 'AdHocWIPData'
) wipdata
GROUP BY wipdata.containerid
      ,wipdata.wiplotid
      ,wipdata.wiptrackinggroupkeyid
      ,wipdata.specid  
      ,wipdata.specname

) WipData

谢谢你们。

4

2 回答 2

0

您可以保留值的顺序,但您必须在之前定义此顺序

基于UNION ALL问题查询第一部分的示例:

SELECT 
      wipData."Transaction Type"
      ,wipData."Details"
      ,wipData."Values"
      ,NULL
      ,wipdata.containerid
      ,wipdata.specid
      ,wipdata.wiptrackinggroupkeyid
      ,wipdata.wiplothistoryid
      ,NULL wipdatasetupid
      ,wipdata.specname
      ,NULL linkid
FROM
(
    SELECT wipdata.containerid
          ,wipdata.wiplothistoryid
          ,wipdata.wiptrackinggroupkeyid
          ,wipdata.specid  
          ,wipdata.specname
          ,'WIP Data Collection @'|| SUBSTR(wipdata.specname,0,4) AS "Transaction Type"
          ,LISTAGG(wipdata.wipdatanamename ||': ' , 'break') 
              --- order by row number of inner query
              WITHIN GROUP ( ORDER BY ordered_row_number) AS "Details" 
          ,LISTAGG(wipdata.wipdatavalue, 'break') 
              --- order by row number of inner query
             WITHIN GROUP ( ORDER BY ordered_row_number) AS "Values" 
    FROM
    (
      SELECT c.containerid
            ,wldd.wipdatanamename
            ,wldd.wipdatavalue
            ,wldd.iswaferdata
            ,wl.specname
            ,wl.wiplothistoryid
            ,wl.wiptrackinggroupkeyid
            ,wl.specid
            ------- store number of the row in defined order ----------------- 
            , rownum as ordered_row_number
            ------------------------------------------------------------------  
      FROM Container C
      JOIN a_wiplothistory wl ON c.containerid = wl.containerid
      JOIN a_wiplotdetailshistory wld ON wl.wiplothistoryid = wld.wiplothistoryid
      JOIN a_wiplotdetailsdatahistory wldd ON wld.wiplotdetailshistoryid = wldd.wiplotdetailshistoryid
      WHERE c.containername = :lotID AND wldd.iswaferdata = 0 AND wldd.servicename <> 'AdHocWIPData'
      ---- !!! Ordering definition mandatory to get predictable results !!! ----
      ORDER BY c.containername, wldd.servicename
      --------------------------------------------------------------------------
    ) wipdata
    GROUP BY wipdata.containerid
          ,wipdata.wiplothistoryid
          ,wipdata.wiptrackinggroupkeyid
          ,wipdata.specid  
          ,wipdata.specname

) WipData

在您的情况下,只需指定即可获得与上述示例相同的结果

 LISTAGG(...) WITHIN GROUP (ORDER BY c.containername, wldd.servicename)

所以现在需要进行内部查询修改。

如果您只是不担心值的顺序,请listagg()使用任何常量 in ORDER BY

 LISTAGG(...) WITHIN GROUP (ORDER BY 'No order')

我尝试在 listagg (SQLFiddle)中直接使用 rownum ,它适用于简单查询,但也取决于执行计划,因此不能保证保留记录顺序。

更新

使用分析功能可以达到相同的效果row_number()

SELECT 
      wipData."Transaction Type"
      ,wipData."Details"
      ,wipData."Values"
      ,NULL
      ,wipdata.containerid
      ,wipdata.specid
      ,wipdata.wiptrackinggroupkeyid
      ,wipdata.wiplothistoryid
      ,NULL wipdatasetupid
      ,wipdata.specname
      ,NULL linkid
FROM
(
    SELECT wipdata.containerid
          ,wipdata.wiplothistoryid
          ,wipdata.wiptrackinggroupkeyid
          ,wipdata.specid  
          ,wipdata.specname
          ,'WIP Data Collection @'|| SUBSTR(wipdata.specname,0,4) AS "Transaction Type"
          ,LISTAGG(wipdata.wipdatanamename ||': ' , 'break') 
              --- order by row number of inner query
              WITHIN GROUP ( ORDER BY ordered_row_number) AS "Details" 
          ,LISTAGG(wipdata.wipdatavalue, 'break') 
              --- order by row number of inner query
             WITHIN GROUP ( ORDER BY ordered_row_number) AS "Values" 
    FROM
    (
      SELECT c.containerid
            ,wldd.wipdatanamename
            ,wldd.wipdatavalue
            ,wldd.iswaferdata
            ,wl.specname
            ,wl.wiplothistoryid
            ,wl.wiptrackinggroupkeyid
            ,wl.specid
            ------- store number of the row in defined order ----------------- 
            , row_number() over (order by c.containername, wldd.servicename) as ordered_row_number
            ------------------------------------------------------------------  
      FROM Container C
      JOIN a_wiplothistory wl ON c.containerid = wl.containerid
      JOIN a_wiplotdetailshistory wld ON wl.wiplothistoryid = wld.wiplothistoryid
      JOIN a_wiplotdetailsdatahistory wldd ON wld.wiplotdetailshistoryid = wldd.wiplotdetailshistoryid
      WHERE c.containername = :lotID AND wldd.iswaferdata = 0 AND wldd.servicename <> 'AdHocWIPData'
    ) wipdata
    GROUP BY wipdata.containerid
          ,wipdata.wiplothistoryid
          ,wipdata.wiptrackinggroupkeyid
          ,wipdata.specid  
          ,wipdata.specname

) WipData
于 2013-07-03T06:49:26.313 回答
-1

尝试改用 stgagg 函数:http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID: 15637744429336

于 2013-07-03T04:58:41.273 回答