我哪里错了?为什么在添加 MAX 函数时会收到该消息?
查询涉及:
WITH
references_cve AS (
SELECT vulnerability_id, reference
FROM dim_vulnerability_reference
WHERE dim_vulnerability_reference.source = 'NVD'
)
SELECT DISTINCT ON (
da.ip_address,
favi.port,
dv.severity,dp.name, dv.title,
dv.description,
fix,
dv.nexpose_id,
cve.reference,
da.host_name,
dos.description,
da.last_assessed_for_vulnerabilities,
davbs.solution_id
)
da.ip_address AS IPAddress,
CASE WHEN favi.port = -1 THEN NULL ELSE favi.port END AS Port,
dv.severity AS Severity,
dp.name AS Protocol,
dv.title AS VulnerabilityName,
htmlToText(dv.description) AS Summary,
htmlToText(dv.description) AS Description,
htmlToText(fix) as Solution,
'https://www.rapid7.com/db/vulnerabilities/' || dv.nexpose_id as SeeAlso,
dv.nexpose_id AS NexposeID,
''||null as PluginOutput,
cve.reference as CVE,
''||null as APPorOS,
''||null as BU,
da.host_name as DEVICENAME,
date(da.last_assessed_for_vulnerabilities) as LastScanDate,
dos.description as DeviceOperatingSystem,
MAX(sr.solution_id),
davbs.vulnerability_id,
dv.vulnerability_id
FROM fact_asset_vulnerability_instance favi
LEFT JOIN dim_asset da USING (asset_id)
LEFT JOIN dim_vulnerability dv USING (vulnerability_id)
LEFT JOIN dim_site_asset dsa USING (asset_id)
LEFT JOIN dim_site ds USING (site_id)
LEFT JOIN dim_vulnerability_status dvs USING (status_id)
LEFT JOIN dim_protocol dp USING (protocol_id)
LEFT JOIN dim_service dsvc USING (service_id)
LEFT JOIN dim_operating_system dos USING (operating_system_id)
LEFT JOIN dim_asset_vulnerability_best_solution davbs ON da.asset_id = davbs.asset_id AND dv.vulnerability_id = davbs.vulnerability_id
LEFT JOIN dim_solution sr on davbs.solution_id = sr.solution_id
LEFT JOIN references_cve cve on favi.vulnerability_id = cve.vulnerability_id
ORDER BY da.ip_address
Run Code Online (Sandbox Code Playgroud)
结果消息:
错误:列“da.ip_address”必须出现在 GROUP BY 子句中或用于聚合函数
字符:456
我假设您使用的是 PostgreSQL。
我想 - 我无法重现你的整个查询 - 你收到这个错误是因为你添加了一个聚合:
MAX(sr.solution_id)
Run Code Online (Sandbox Code Playgroud)
我已经建立了一个最小的例子来重现这个错误:
CREATE TABLE t(id INT, foo int, bar int);
INSERT INTO t VALUES
(1, 10, 20),
(1, 11, 21),
(1, 12, 22),
(2, 30, 40),
(2, 31, 41),
(2, 32, 42);
Run Code Online (Sandbox Code Playgroud)
使用类似的语法:
SELECT
DISTINCT ON (id) id,
foo,
MAX(bar) bar
FROM
t
ORDER BY
id, foo;
Run Code Online (Sandbox Code Playgroud)
它返回下一个错误:
错误:列“t.id”必须出现在 GROUP BY 子句中或用于聚合函数第 2 行:DISTINCT ON (id) id,
解决它的一个想法是使用子查询来计算聚合值(但这并不像人们期望的那样工作):
SELECT
DISTINCT ON (id) id,
foo,
(SELECT
MAX(bar)
FROM
t t1
WHERE
t1.id = t.id) max_bar
FROM
t
ORDER BY
id, max_bar;
Run Code Online (Sandbox Code Playgroud)
身份证 | 富| 最大栏 -: | --: | ------: 1 | 10 | 22 2 | 30 | 42
假设您想要每行一行id,即具有最大值的行bar,那么这就是如何使用DISTINCT ON:
SELECT
DISTINCT ON (id) id,
foo,
bar
FROM
t
ORDER BY
id, bar DESC;
Run Code Online (Sandbox Code Playgroud)
身份证 | 富| 最大栏 -: | --: | ------: 1 | 12 | 22 2 | 32 | 42
db<>在这里摆弄
使用DISTINCT ON和在澄清一点要求的评论之后,您希望每个漏洞都有一行 - 标识为dv.nexpose_id:
查询每个漏洞都有一行,但是,某些漏洞有 1 个以上的解决方案,这会导致该行重复但具有不同的解决方案 ID。我只需要每行 1 个解决方案 ID。
Nexpose ID 用于识别漏洞。
您的查询应该被重写:
WITH
references_cve AS (
SELECT vulnerability_id, reference
FROM dim_vulnerability_reference
WHERE dim_vulnerability_reference.source = 'NVD'
)
SELECT DISTINCT ON (
dv.nexpose_id -- one result for each vulnearibility
)
da.ip_address AS IPAddress,
-- ...
dos.description as DeviceOperatingSystem,
sr.solution_id, --<-- This is changed
davbs.vulnerability_id,
dv.vulnerability_id
FROM fact_asset_vulnerability_instance favi
LEFT JOIN dim_asset da USING (asset_id)
-- ...
ORDER BY
dv.nexpose_id, -- same as the DISTNCT ON
sr.solution_id DESC -- plus the ordering we want
;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
579 次 |
| 最近记录: |