查找与列的平均值匹配的行
Finding rows which match the average value of a column
我正在使用 Oracle 11g。我有几张看起来像这样的表格(稍微简化了一点)。
CREATE TABLE clients (
id NUMBER(10) NOT NULL,
gridx NUMBER(10),
gridy NUMBER(10),
CONSTRAINT clients_pk PRIMARY KEY (id)
);
CREATE TABLE requests (
id NUMBER(10) NOT NULL,
client_id NUMBER(10),
CONSTRAINT clients_fk FOREIGN KEY (client_id) REFERENCES clients(id),
CONSTRAINT requests_pk PRIMARY KEY (id)
);
我需要找到看到平均请求数的网格部分。到目前为止,我提出了以下查询,其中列出了为每个不同的网格位置发出的请求数。
SELECT joined_tbl.gridx, joined_tbl.gridy, COUNT(joined_tbl.id) requests_cnt FROM (
SELECT c.gridx, c.gridy, r.id
FROM requests r
INNER JOIN clients c ON c.id=r.client_id GROUP BY c.gridx, c.gridy, r.id ORDER BY r.id
) joined_tbl
GROUP BY joined_tbl.gridx, joined_tbl.gridy;
这给出了以下输出
GRIDX GRIDY REQUESTS_CNT
1 -3 2
2 5 4
-1 -3 4
-3 -2 6
接下来我需要取 REQUESTS_CNT 列的平均值并列出所有与平均值匹配的行。我该怎么做?我不能在我考虑过的 WHERE 子句中使用 AVG 函数,所以我应该使用 HAVING 吗?
您的查询可以归结为:
SELECT c.gridx, c.gridy, COUNT(*) AS requests_cnt
FROM requests r
JOIN clients c ON c.id = r.client_id
GROUP BY c.gridx, c.gridy;
即获取每个 gridx/gridy 的请求计数。您想要确定平均计数,然后仅显示恰好出现频率为 gridx/gridy 的对。在您的示例中,这将是 (2|5)、(-1|-3) 对,但我猜大多数情况下根本就没有对。
最简单的方法似乎是通过应用 AVG OVER
:
来获得平均值 on-the-fly
SELECT gridx, gridy
FROM
(
SELECT
c.gridx, c.gridy, COUNT(*) AS requests_cnt,
AVG(COUNT(*)) OVER () AS avg_requests_cnt
FROM requests r
JOIN clients c ON c.id = r.client_id
GROUP BY c.gridx, c.gridy
) pairs
WHERE requests_cnt = avg_requests_cnt
ORDER BY gridx, gridy;
我正在使用 Oracle 11g。我有几张看起来像这样的表格(稍微简化了一点)。
CREATE TABLE clients (
id NUMBER(10) NOT NULL,
gridx NUMBER(10),
gridy NUMBER(10),
CONSTRAINT clients_pk PRIMARY KEY (id)
);
CREATE TABLE requests (
id NUMBER(10) NOT NULL,
client_id NUMBER(10),
CONSTRAINT clients_fk FOREIGN KEY (client_id) REFERENCES clients(id),
CONSTRAINT requests_pk PRIMARY KEY (id)
);
我需要找到看到平均请求数的网格部分。到目前为止,我提出了以下查询,其中列出了为每个不同的网格位置发出的请求数。
SELECT joined_tbl.gridx, joined_tbl.gridy, COUNT(joined_tbl.id) requests_cnt FROM (
SELECT c.gridx, c.gridy, r.id
FROM requests r
INNER JOIN clients c ON c.id=r.client_id GROUP BY c.gridx, c.gridy, r.id ORDER BY r.id
) joined_tbl
GROUP BY joined_tbl.gridx, joined_tbl.gridy;
这给出了以下输出
GRIDX GRIDY REQUESTS_CNT 1 -3 2 2 5 4 -1 -3 4 -3 -2 6
接下来我需要取 REQUESTS_CNT 列的平均值并列出所有与平均值匹配的行。我该怎么做?我不能在我考虑过的 WHERE 子句中使用 AVG 函数,所以我应该使用 HAVING 吗?
您的查询可以归结为:
SELECT c.gridx, c.gridy, COUNT(*) AS requests_cnt
FROM requests r
JOIN clients c ON c.id = r.client_id
GROUP BY c.gridx, c.gridy;
即获取每个 gridx/gridy 的请求计数。您想要确定平均计数,然后仅显示恰好出现频率为 gridx/gridy 的对。在您的示例中,这将是 (2|5)、(-1|-3) 对,但我猜大多数情况下根本就没有对。
最简单的方法似乎是通过应用 AVG OVER
:
SELECT gridx, gridy
FROM
(
SELECT
c.gridx, c.gridy, COUNT(*) AS requests_cnt,
AVG(COUNT(*)) OVER () AS avg_requests_cnt
FROM requests r
JOIN clients c ON c.id = r.client_id
GROUP BY c.gridx, c.gridy
) pairs
WHERE requests_cnt = avg_requests_cnt
ORDER BY gridx, gridy;