按 SUBSTR 分组

Group by SUBSTR

谁能给我解释一下为什么下面的代码没有错误:

SELECT t1.column1,
       t1.column2,
       t1.column3,
       ctot as Cost,
       (ctot * t1.qty) as FinalCost
FROM Table1 t1

LEFT JOIN (SELECT column1,
                  column2,
                  column3,
                  column4,
             MAX(DateCol),
             AVG(CostCol) KEEP(DENSE_RANK LAST ORDER BY t2.DateCol) as ctot
FROM Table2 t2
GROUP BY column1, column2, SUBSTR(column3, 1, 5), column4) t2
     ON t2.column1 = t1.column1
     AND t2.column2 = t1.column2
     AND t2.column4 = t1.column4
     AND SUBSTR(t1.column3, 1, 5) = SUBSTR(t2.column3, 1, 5)
     WHERE t1.ID1 = '500'
     AND t1.ID2 != '50'

虽然此代码会产生错误 ORA-00979: not a GROUP BY expression:

SELECT t1.column1,
       t1.column2,
       t1.column3,
       ctot as Cost,
       (ctot * t1.qty) as FinalCost
FROM Table1 t1

LEFT JOIN Table2 t2
    ON t1.column1 = t2.column1
   AND t1.column2 = t2.column2

LEFT JOIN (SELECT IdCol as points, column3 FROM Table3) t3
    ON t2.column3 = t3.column3

LEFT JOIN (SELECT column1,
                  column3,
             MAX(DateCol),
             AVG(CostCol) KEEP(DENSE_RANK LAST ORDER BY t4.DateCol) as ctot
FROM Table4 t4
GROUP BY column1, SUBSTR(column3, 1, 5)) t4
    ON t4.column1 = points
   AND SUBSTR(t4.column3, 1, 5) = SUBSTR(t1.column3, 1, 5)
 WHERE t1.ID1 = '500'
   AND t1.ID2 != '50'

我的编辑在我的最终连接语句中突出显示 column3 作为错误的原因,并在 GROUP BY 语句中将 SUBSTR(column3, 1, 5) 替换为 column3 修复了此错误。但是为什么在第二个示例中抛出错误而不是在第一个示例中抛出错误?是否与多个连接语句有关?

在语句末尾额外)...

应该只是

SELECT
  t1.column1,
  t1.column2,
  t1.column3,
  ctot AS Cost,
  (ctot * t1.qty) AS FinalCost
FROM Table1 t1

LEFT JOIN (SELECT
  column1,
  column2,
  column3,
  column4,
  MAX(DateCol),
  AVG(CostCol) KEEP (DENSE_RANK LAST ORDER BY t2.DateCol) AS ctot
FROM Table2 t2
GROUP BY column1,
         column2,
         SUBSTR(column3, 1, 5),
         column4) t2

  ON t2.column1 = t1.column1
  AND t2.column2 = t1.column2
  AND t2.column4 = t1.column4
  AND SUBSTR(t1.column3, 1, 5) = SUBSTR(t2.column3, 1, 5)
WHERE t1.ID1 = '500'
AND t1.ID2 != '50'

您在主 select 中使用 LEFT JOIN,这意味着 Oracle 正在使用 SQL92。所以你必须在 GROUP BY 中使用 clausule exat SELECT 投影的一部分。

e.i。在 subselect:

中使用它
SELECT column1,
    column2,
    SUBSTR(column3, 1, 5) as column3, -- column3 after substr()
    column4,
    MAX(DateCol),
    AVG(CostCol) KEEP(DENSE_RANK LAST ORDER BY t2.DateCol) AS ctot
FROM Table2 t2
GROUP BY column1, column2, SUBSTR(column3, 1, 5), column4