使用 COUNT(*) 和 GROUP BY 重写查询作为 Cartesian Join

Rewrite query with COUNT(*) and GROUP BY as Cartesian Join

请问是否可以改写如下查询:

SELECT TEAM, COUNT(*)
FROM
(
    SELECT    ID, TEAM
    FROM      MY_TABLE
    WHERE     TO_CHAR(A.SUBMIT_DATE, 'YYYY') = '2019' 
    GROUP BY  ID, TEAM
)
GROUP BY TEAM

使用笛卡尔连接方式? 原因是我使用的是 Peoplesoft,它不允许在不为其创建另一个视图的情况下进行此类子查询。

您的内部查询正在拉平 table 以获得 2019 年的不同 IDTEAM 组合,然后由外部查询对其进行计数。您可以将其简化为一个简单的 COUNT(DISTINCT) 查询:

SELECT TEAM, COUNT(DISTINCT ID)
FROM MY_TABLE
WHERE TO_CHAR(SUBMIT_DATE, 'YYYY') = '2019'
GROUP BY TEAM;

注意:

  • 正如 Gary Myers 在评论中指出的那样,如果存在 ID 空值,这将不起作用。如果 ID 可以为空,请参阅下一个要点。
  • 下面注释中来自 Tejash 的精彩 hack,如果 ID 可以为 NULL:

    SELECT TEAM, COUNT(DISTINCT ID || TEAM)
    ... and then the rest of the query from above
    

Here's a Fiddle with your query and mine. Tejash also did a fiddle.

还有一件事。如果您有很多记录(数千条或更多),并且在 SUBMIT_DATE 上有索引,则可以使用 [=19] 上的函数 not 优化查询=]:

SELECT TEAM, COUNT(DISTINCT ID)
FROM MY_TABLE
WHERE SUBMIT_DATE >= DATE '2019-01-01'
  AND SUBMIT_DATE <  DATE '2020-01-01'
GROUP BY TEAM;

如果它是一个很大的table,有很多行和很多年,优化版本会明显更快。