gpt4 book ai didi

sql - 复杂的 SQL 查询有助于聚合嵌套子查询的值

转载 作者:行者123 更新时间:2023-11-29 13:38:07 24 4
gpt4 key购买 nike

我有人物、公司、员工、事件和事件类型。我正在制作一份报告/跟进表,其中行是人员、公司和员工,而列是事件类型。

事件类型是简单的值,描述:“ promise 捐赠”、“收到捐赠”、“已调用”、“已跟进”等。事件类型是有序的:

CREATE TABLE event_kinds (
id,
name,
position);

事件持有对事件的实际引用:

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);

我正在努力实现以下报告:

                         Referrer       Phoned     Promised   Donated    Francois                            Feb 16th   Feb 20th   Mar 1st    Apple (Steve Jobs)   Steve Ballmer                        Mar 3rd    IBM                  Bill Gates     Mar 7th

The first row is a people record, the 2nd is an employee, and the 3rd is a company. If I asked for referrer Bill Gates for Phoned event kinds, I'd only see the 3rd row, while asking for Steve and Phoned would return no rows.

Right now, I do 3 queries, one for companies, one for people and a last one for employees. I want the event kind columns to be ordered, but I do that in application code and show it properly there. Here's where I'm at so far:

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。

最佳答案

同一个人/公司和 event_kind_id 是否可以有多个行(例如 Bill Gates Phoned on 07-Mar and 09-Mar)?如果没有,您可以执行以下操作:

Select Coalesce(People.name, Companies.name) As Name
, Referrers.name
, Min(Case When EventKinds.name = 'Phoned' Then Events.created_at End) As Phoned
, Min(Case When EventKinds.name = 'Promised' Then Events.created_at End) As Promised
, Min(Case When EventKinds.name = 'Donated' Then Events.created_at End) As Donated
From Events
Join EventKinds
On EventKinds.id = Events.event_kind_id
Left Join People As Referrers
On Referrers.id = Events.referrer_id
Left Join People
On People.id = Events.person_id
Left Join Companies
On Companies.id = Events.company_id
-- Where Companies.Name Like 'foo%'
Group By Coalesce(People.name, Companies.name), Referrers.name

关于sql - 复杂的 SQL 查询有助于聚合嵌套子查询的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2430600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com