使用 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 年的不同 ID
和 TEAM
组合,然后由外部查询对其进行计数。您可以将其简化为一个简单的 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,有很多行和很多年,优化版本会明显更快。
请问是否可以改写如下查询:
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 年的不同 ID
和 TEAM
组合,然后由外部查询对其进行计数。您可以将其简化为一个简单的 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,有很多行和很多年,优化版本会明显更快。