【发布时间】:2010-03-12 04:59:42
【问题描述】:
我有人员、公司、员工、事件和事件类型。我正在制作一个报告/跟进表,其中人员、公司和员工是行,列是事件类型。
事件种类是简单的值描述:“承诺的捐赠”、“收到的捐赠”、“电话”、“跟进”等。事件种类排序:
CREATE TABLE event_kinds (
id,
name,
position);
Events 持有对事件的实际引用:
CREATE TABLE events (
id,
person_id,
company_id,
referrer_id,
event_kind_id,
created_at);
referrer_id 是对人的另一个引用。它是发送信息/提示的人,并且是一个可选字段,尽管我有时想过滤具有特定引荐来源的 event_kind,而我不过滤其他事件类型。
请注意,我没有员工 ID 参考。引用存在,但被暗示。我有应用程序代码来验证 person_id 和 company_id 确实引用了员工记录。其他表非常基本:
CREATE TABLE people (
id, name);
CREATE TABLE companies (
id, name);
CREATE TABLE employees (
id, person_id, company_id);
我正在努力实现以下报告:
推荐人 打电话 承诺 捐赠 弗朗索瓦 2 月 16 日 2 月 20 日 3 月 1 日 苹果(史蒂夫·乔布斯)史蒂夫·鲍尔默 3 月 3 日 IBM 比尔盖茨 3 月 7 日第一行是人员记录,第二行是员工,第三行是公司。如果我向 Bill Gates 询问 Phoned 事件类型,我只会看到第 3 行,而询问 Steve 和 Phoned 则不会返回任何行。
现在,我做了 3 个查询,一个是针对公司的,一个是针对人员的,最后一个是针对员工的。我希望对事件类型列进行排序,但我在应用程序代码中这样做并在那里正确显示。这是我目前所处的位置:
SELECT companies.id,
companies.name,
(SELECT events.id FROM events WHERE events.referrer_id = 1470 AND events.company_id = companies.id AND events.person_id IS NULL AND events.event_kind_id = 9 ORDER BY created_at DESC LIMIT 1) event_kind_9,
(SELECT events.id FROM events WHERE events.company_id = companies.id AND events.person_id IS NULL AND events.event_kind_id = 10 ORDER BY created_at DESC LIMIT 1) event_kind_10,
(SELECT events.created_at FROM events WHERE events.referrer_id = 1470 AND events.company_id = companies.id AND events.person_id IS NULL AND events.event_kind_id = 9 ORDER BY created_at DESC LIMIT 1) event_kind_9_order
FROM "companies"
SELECT people.id,
people.name,
(SELECT events.id FROM events WHERE events.referrer_id = 1470 AND events.company_id IS NULL AND events.person_id = people.id AND events.event_kind_id = 9 ORDER BY created_at DESC LIMIT 1) event_kind_9,
(SELECT events.id FROM events WHERE events.company_id IS NULL AND events.person_id = people.id AND events.event_kind_id = 10 ORDER BY created_at DESC LIMIT 1) event_kind_10,
(SELECT events.created_at FROM events WHERE events.referrer_id = 1470 AND events.company_id IS NULL AND events.person_id = people.id AND events.event_kind_id = 9 ORDER BY created_at DESC LIMIT 1) event_kind_9_order
FROM "people"
SELECT employees.id,
employees.company_id,
employees.person_id,
(SELECT events.id FROM events WHERE events.referrer_id = 1470 AND events.company_id = employees.company_id AND events.person_id = employees.person_id AND events.event_kind_id = 9 ORDER BY created_at DESC LIMIT 1) event_kind_9,
(SELECT events.id FROM events WHERE events.company_id = employees.company_id AND events.person_id = employees.person_id AND events.event_kind_id = 10 ORDER BY created_at DESC LIMIT 1) event_kind_10,
(SELECT events.created_at FROM events WHERE events.referrer_id = 1470 AND events.company_id = employees.company_id AND events.person_id = employees.person_id AND events.event_kind_id = 9 ORDER BY created_at DESC LIMIT 1) event_kind_9_order
FROM "employees"
我宁愿怀疑我做错了。应该有一种“更简单”的方法来做到这一点。
另一个过滤条件是过滤人员/公司名称:WHERE LOWER(companies.name) LIKE '%apple%'。
请注意,我在这里按 event_kind_9 的日期排序,次要排序是按个人/公司名称。
总结一下:我想对结果集进行分页,找到每个单元格的最新事件,按最新事件的日期和公司/人名对结果集进行排序,在某些事件类型中按推荐人过滤,但是不是其他人。
作为参考,我正在使用来自 Ruby、ActiveRecord/Rails 的 PostgreSQL。解决方案是纯 SQL。
【问题讨论】:
标签: sql postgresql