簡體   English   中英

使用 sum 時避免使用 group by

[英]Avoid to use group by when using sum

我是SQL/ORACLE新手。 我正在嘗試編寫一個查詢以獲得所需的結果。 我也在 select 語句中使用 sum 函數,然后我還必須在group by子句中寫入select中的所有列。 有什么辦法可以避免使用這種方法。 下面是我的查詢,它給了我想要的結果,我只想擺脫group by子句。

SELECT
    T1.ORDER_CODE "ORDER NUMBER",
    T1.ORDER_ITEM "ORDER ITEM",
    T1.ROLL_SHEET,
    T1.ORDER_STATUS "ORDER ITEM STATUS",
    T1.ORDER_TYPE "ORDER_TYPE",
    T2.ORDER_STATUS_SALES "SALES ORDER STATUS",
    T1.CLASSIFICATION "GRADE",
    T1.PRODUCT_CODE "PRODUCT", 
    T1.ARTICLE_CODE "ARTICLE",
    T1.WIDTH || 'x' || T1.LENGTH || 'x' || NVL((NULLIF(T1.HEIGHT_PALLET,0)),T1.DIAMETER) "SIZE", 
    T2.DATE_CUST_ISSUED "ORDERED DATE", 
    T2.DATE_CONFIRMED "CONFIRMATION DATE",
    T1.DATE_EXMILL "EXMILL DATE",
    T1.MASS_ORDERED "ORDERED",
    T3.MASS_TRIMMED "TRIMMED", 
    T3.MASS_WOUND "PRODUCED",
    T3.MASS_SCALED "WRAPPED",
    SUM(T4.MASS) "IN WH"
FROM ORDERITEM T1 
INNER JOIN ORDERHEADER T2 ON T1.ORDER_CODE = T2.ORDER_CODE
LEFT OUTER JOIN MACHINERUNORDERITEM T3 ON T1.ORDER_CODE = T3.ORDER_CODE AND T1.ORDER_ITEM = T3.ORDER_ITEM
LEFT OUTER JOIN ORDERITEMINVENTORY T4 ON T1.ORDER_CODE = T4.ORDER_CODE AND T1.ORDER_ITEM = T4.ORDER_ITEM
WHERE T1.ORDER_CODE = '1000000294'
GROUP BY T1.ORDER_CODE, T1.ORDER_ITEM, T1.ROLL_SHEET, T1.ORDER_STATUS,
         T1.ORDER_TYPE, T2.ORDER_STATUS_SALES, T1.CLASSIFICATION,
         T1.PRODUCT_CODE, T1.ARTICLE_CODE,
         T1.WIDTH || 'x' || T1.LENGTH || 'x' || NVL((NULLIF(T1.HEIGHT_PALLET,0)),T1.DIAMETER),
         T2.DATE_CUST_ISSUED, T2.DATE_CONFIRMED, T1.DATE_EXMILL,
         T1.MASS_ORDERED, T3.MASS_TRIMMED, T3.MASS_WOUND, T3.MASS_SCALED

嗯,你不能。 它是 SYNTAX 的一部分。

如果使用 SUM,則以集合(而不是逐行)進行思考的 SQL 必須具有 GROUP BY 子句。 當您在 SELECT 語句中請求一列時,SQL(在本例中為 Oracle)會為您提供這些列。 如果你想求和,它需要知道要 GROUP BY 的內容,否則,它只會對所有內容求和。 就這樣。 我建議您閱讀有關W3 學校中的 GROUP BY 子句和 SUM 函數的更多信息,以便更好地理解該問題。

構建非平凡GROUP BY語句的典型方法是編寫第一部分並復制GROUP BY子句中的分組列

select 
COL1 ||'-' || COL2 as x,
case when COL1 = 'A1' then COL2 ||'-' || COL1 else COL1 || '-' || COL2 end as y,
sum(COL3)
from tab
group by COL1 ||'-' || COL2 as x,
case when COL1 = 'A1' then COL2 ||'-' || COL1 else COL1 || '-' || COL2 end as y;

這會導致錯誤:

ORA-00933: SQL command not properly ended

並且是已知的痛點(有趣的是並非所有人) - 請參閱Oracle Ideas Page 中的討論

所以下一步是從GROUP BY子句中刪除別名,該語句有效......

select 
COL1 ||'-' || COL2 as x,
case when COL1 = 'A1' then COL2 ||'-' || COL1 else COL1 || '-' || COL2 end as y,
sum(COL3)
from tab
group by COL1 ||'-' || COL2,
case when COL1 = 'A1' then COL2 ||'-' || COL1 else COL1 || '-' || COL2 end;

...但這是一個臭代碼的經典示例,其中每個更改都必須在兩個地方以相同的方式進行。

不太了解,但它的工作原理是您不需要復制GROUP BY列的確切表達式,所有使用的原始列的列表就足夠了

這里有一個例子COL1, COL2 GROUP BY COL1, COL2涵蓋了SELECT使用的所有表達式

select 
COL1 ||'-' || COL2 as x,
case when COL1 = 'A1' then COL2 ||'-' || COL1 else COL1 || '-' || COL2 end as y,
sum(COL3)
from tab
group by COL1, COL2

X     Y      SUM(COL3)
----- ----- ----------
A1-B1 B1-A1          1 
A3-B3 A3-B3          3 
A2-B2 A2-B2          2 

我的測試數據

create table tab as
select 'A1' col1, 'B1' col2, 1 col3 from dual union all
select 'A2' col1, 'B2' col2, 2 col3 from dual union all
select 'A3' col1, 'B3' col2, 3 col3 from dual;

假設T4是導致“重復”的原因,您只需使用相關子查詢即可解決此問題:

select . . .,
       (select sum(oit.mass)
        from ORDERITEMINVENTORY oii 
        where T1.ORDER_CODE = oii.ORDER_CODE AND T1.ORDER_ITEM = oii.ORDER_ITEM
       )
from . . .  -- leave `T4` out of this clause

不需要GROUP BY 這可能也會有更好的性能。

請注意,這“似乎”僅適用於一個聚合列——它解決了您的直接問題。 Oracle 12C 支持橫向連接,這將允許“相關”子查詢中的多個列。

此外,我強烈建議您使用有意義的表別名。 在此代碼片段中,我將無意義的T4替換為oii ,即表名中每個單詞的首字母。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM