使用group by计算查询中的列

时间:2015-07-17 07:36:21

标签: sql postgresql

我有下表

  id integer NOT NULL DEFAULT nextval('cl_id_seq'::regclass),
  from_number character varying(30),
  to_number character varying(30),
  message text,
  received_at timestamp with time zone,
  sent_at timestamp with time zone,
  reply_batch boolean DEFAULT false,
  chat_id character varying(20),
  insert_time timestamp with time zone DEFAULT now(),
  own_account boolean DEFAULT false,

我有以下查询,只有当与chat_id相关的最后一条消息(由insert_time列检查)的列own_account为false时,才会返回会话的chat_id。

select chat_id from message_log 
where own_account = 'f'
and insert_time in
(
select distinct max(insert_time) from message_log group by chat_id
)

上面的SQL工作正常,但它返回会话而不检查聊天中own_account列的真实次数。我想基于own_account为真的次数添加返回会话的chat_id的功能。

我尝试了很多不同的SQL查询但是我无法成功完成这项工作。任何帮助将不胜感激。

我希望我足够清楚。如果对任何事情感到困惑,请发表评论。

修改

我已经在SQL Fiddle上加载了数据

http://sqlfiddle.com/#!15/1d7dc/2

如果运行以下查询,它将返回与聊天对话相关的消息

select * from message_log where chat_id = '1412' order by insert_time

最后一条消息不是来自own_account,并且结果中有少于3条own_account消息,因此以下查询应该返回它的chat_id,但它不会

select m.chat_id 
from message_log m
inner join 
  (select chat_id, max(insert_time) as max_insert_time,
   count(case when own_account='t' then 1 else 0 end) as true_count
   from message_log
   group by chat_id) as latest
on m.chat_id = latest.chat_id and
   m.insert_time = latest.max_insert_time
where 
   m.own_account = 'f' and latest.true_count <= 3

编辑2

我用一条记录创建了另一个sql小提琴

http://sqlfiddle.com/#!15/ad045/1

1 个答案:

答案 0 :(得分:2)

您可以构建一个派生表,记录所有聊天记录的最新插入时间,然后查明该最新记录是否为own_account='f'

select m.chat_id 
from message_log m
inner join 
  (select chat_id, max(insert_time) as max_insert_time
   from message_log
   group by chat_id) as latest
on m.chat_id = latest.chat_id and
   m.insert_time = latest.max_insert_time
where 
   m.own_account = 'f' 

扩展它以查找最新为own_account ='f'但至少有3 own_account='t'个条目的聊天

select m.chat_id 
from message_log m
inner join 
  (select chat_id, max(insert_time) as max_insert_time,
   sum(case when own_account='t' then 1 else 0 end) as true_count
   from message_log
   group by chat_id) as latest
on m.chat_id = latest.chat_id and
   m.insert_time = latest.max_insert_time
where 
   m.own_account = 'f' and latest.true_count >= 3

SQLFiddle可在http://sqlfiddle.com/#!15/ee8c0/2

获得