我创建了这个sqlfiddle来执行此查询:
SELECT "emails".*
FROM (
SELECT "emails".id, sender_contact_id, sender_user_id,
rank() OVER (PARTITION BY "sender_contact_id" ORDER BY "sent_at" DESC) AS "contact_rnk",
rank() OVER (PARTITION BY "sender_user_id" ORDER BY "sent_at" DESC) AS "user_rnk"
FROM "emails"
WHERE ("folder" = 'INBOX')
) AS "e"
INNER JOIN "emails"
ON ("emails"."id" = "e"."id")
WHERE ((contact_rnk = 1 or user_rnk = 1) AND folder = 'INBOX')
ORDER BY sent_at DESC;
查询的目的是为每个发送电子邮件的联系人或用户仅返回1行。
查询中缺少的是为每个分区用户或联系人发送的电子邮件数。
我可以使用查询做多个并最后加入,例如
with main as (
select blbah, etc.
),
cnt_users as (
select count(sender_user_id) inner join main etc.
),
cnt_contacts as (
select count(sender_contact_id) inner join main etc.
)
select main.*, cntusers etc.
但是,是否可以在第一个查询中包含计数而无需使用group by
?
答案 0 :(得分:0)
行可以在没有GROUP BY
的每个分区内计算,诀窍是使用正确的框架。
例如,查询可以修改为:
SELECT "emails".*, e.*
FROM (
SELECT "emails".id, sender_contact_id, sender_user_id,
rank() OVER (w1) AS "contact_rnk",
count(*) OVER (w1 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS contact_count,
rank() OVER (w2) AS "user_rnk",
count(*) OVER (w2 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS user_count
FROM "emails"
INNER JOIN email_participants ep
ON emails.id = ep.email_id
WHERE (folder = 'INBOX') and user_id = 220
WINDOW
w1 as (PARTITION BY sender_contact_id ORDER BY sent_at DESC),
w2 as (PARTITION BY sender_user_id ORDER BY sent_at DESC)
) AS e
INNER JOIN emails
ON (emails.id = e.id)
WHERE ((contact_rnk = 1 or user_rnk = 1) AND folder = 'INBOX')
ORDER BY sent_at DESC
然后e.contact_count
和e.user_count
应分别包含每个不同sender_contact_id
和sender_user_id
的邮件计数。