1

一般来说,我对 sql 的经验并不丰富,我正在尝试完成一项非常具体的任务——我想首先运行一个查询以获取我所有命中次数最多的单元的 ID,然后从该运行中获取再次获取特定时间段内这些 ID 的所有命中类型的消息和计数。对于第一个查询,我有这个:

SELECT entity, count(entity) as Count
from plugin_status_alerts
where entered BETWEEN now() - INTERVAL '14 days' AND now()
group by entity
order by count(entity) DESC
limit 10

这导致了这个回报:

"38792";3
"39416";2
"37796";2
"39145";2
"37713";2
"37360";2
"37724";2
"39152";2
"39937";2
"39667";2

这个想法是然后使用该结果集来运行另一个按实体和状态码排序的查询。我试过这样的事情:

SELECT status_code, entity, COUNT(status_code) statusCount
FROM plugin_status_alerts
where updated BETWEEN now() - INTERVAL '14 days' AND now() AND entity IN 
(SELECT id.entity, count(id.entity) as Count
from plugin_status_alerts id
where id.updated BETWEEN now() - INTERVAL '14 days' AND now()
group by id.entity
order by count(id.entity) DESC
limit 10
)
GROUP BY status_code, entity

但我得到了错误

ERROR: subquery has too many columns

我不确定这是否是我应该走的路线,或者我是否应该尝试自我加入 - 无论哪种方式都不确定如何纠正现在发生的事情。

4

2 回答 2

1

使用 aJOIN而不是IN (subquery). 这通常更快,如果需要,您可以使用子查询中的其他值(例如 per 的总计数entity):

SELECT entity, status_code, count(*) AS status_ct
FROM  (
   SELECT entity  -- not adding count since you don't use it, but you could
   FROM   plugin_status_alerts
   WHERE  entered BETWEEN now() - interval '14 days' AND now()
   GROUP  BY entitiy
   ORDER  BY count(*) DESC, entitiy  -- as tie breaker to get stable result
   LIMIT  10
   ) sub
JOIN   plugin_status_alerts USING (entity)
WHERE  updated BETWEEN now() - interval '14 days' AND now()
GROUP  BY 1, 2;

笔记

  • 如果您没有未来的设计条目,您可以简化:

    WHERE  entered > now() - interval '14 days'
    
  • entity由于子查询只返回一个列USING

  • LIMIT 10你按计数排序后很可能会模棱两可。多行可以并列第 10 行。如果没有 中的其他项目ORDER BY,Postgres 会返回任意选择,这可能会也可能不会。但是查询的结果可以在调用之间发生变化,而不会对基础数据进行任何更改。通常,这是不可取的,您应该将列或表达式添加到列表中以打破关系

  • count(*)比做同样的事情要快一点count(status_code)- 除非status_code可以为 null,在这种情况下,您将获得0该行的计数(count()从不返回 null)而不是实际的行计数,这要么是无用的,要么是错误的。在这里使用count(*)任何一种方式。

  • GROUP BY 1, 2只是语法简写。细节:

于 2015-03-18T03:29:48.317 回答
0

当您将第一个查询插入第二个查询并在子句中使用它时,您仍然会在唯一需要一个in时返回两列。in要么这样做:

SELECT status_code, entity, COUNT(status_code) statusCount
FROM plugin_status_alerts
where updated BETWEEN now() - INTERVAL '14 days' AND now() 
AND entity IN (
    SELECT id.entity
    from plugin_status_alerts id
    where id.updated BETWEEN now() - INTERVAL '14 days' AND now()
    group by id.entity
    order by count(id.entity) DESC
    limit 10
)
GROUP BY status_code, entity

或者将第一个查询用作派生表并与之连接。

于 2015-03-17T23:14:15.960 回答