表有重复数据,无法让两个聚合函数在 SQL Query 中工作
Posted
技术标签:
【中文标题】表有重复数据,无法让两个聚合函数在 SQL Query 中工作【英文标题】:Table has duplicate data and can't get two aggregates functions to work in SQL Query 【发布时间】:2016-03-06 02:56:39 【问题描述】:问题在于“地址”表有多个条目,其中用户更新了他们的地址。我只需要最新的。我尝试在“地址”表中使用MAX(uPDATED_AT)
,但出现错误。好吧,我首先编写了下面的代码,并意识到很多行是重复的或接近重复的。我只需要将他们的 last 更改为他们的地址,但在尝试将另一个聚合添加到 HAVING
子句时出现错误。有人可以帮忙吗?我是 SQL 的新手,但很想知道这个问题并在以后纠正它。
顺便说一下,我正在使用 PostgreSQL
Select
last_name,
first_name,
donator,
customer_id,
phone,
address,
city,
state,
zipcode,
events.buyer_id
from events
join addresses on events.buyer_id = addresses.buyer_id
inner join customer_extras on addresses.buyer_id = customer_extras.buyer_id
inner join Customer_roles on events.buyer_id = Customer_roles.buyer_id
inner join People on Customer_roles.buyer_id = People.id
group by
customer_id,
member_status,
events.event_type,
first_name,
last_name,
address,
city,
state,
phone,
donator,
zipcode,
events.buyer_id
HAVING MIN(events.created_at) between '2015-06-01'
and '2015-08-01' and event_type ILIKE 'MEMBER_TABLET%' and member_status IN
('moved','never answered', 'refused', 'complete')
【问题讨论】:
使用dense_rank函数 我会在哪里使用它?并感谢您的评论! 【参考方案1】:您需要使用窗口函数,您的查询将如下所示
select t.*, dense_rank() over (partition by <column_with_duplicate_values> order by <date> desc) dr from ...
以上查询按降序排列。您需要包含在另一个查询中
select * from (<above_query>) q where dr=1;
【讨论】:
我似乎无法让您的排名代码正常工作。你能帮忙吗?我需要知道我的查询适合在哪里或如何。在您的代码此处部分中运行我的代码时出现错误。请,非常感谢您的帮助。我把工作带回家,因为我真的很想尽快完成这项工作。 这是经过测试的查询并为您修改。 “select * from (select * from (select t.*, row_number() over (partition by userid order by date desc) dr from address t) q where q.dr = 1) q1 join ...;”您需要通过在join子句后添加表来进行修改 关于您的回复,我有几个问题。我是 sql 新手,不熟悉 t.* 。这是什么意思?我知道。但不是。 t 是 from 子句中查询的别名 "select t.*, dense_rank() over (partition by假设您的addresses
表有一个名为create_date
的字段(我猜,但您可以使用您的实际字段名称),我想您想使用我最喜欢的分析函数row_number:
with most_recent_address as (
select a.*, row_number() over (partition by buyer_id order by create_date desc) as rn
from addresses as a -- fix is here
)
Select
last_name, first_name, donator, customer_id,
phone, address, city, state, zipcode,
events.buyer_id
from events
join most_recent_address a on events.buyer_id = a.buyer_id and a.rn = 1
inner join customer_extras on addresses.buyer_id = customer_extras.buyer_id
inner join Customer_roles on events.buyer_id = Customer_roles.buyer_id
inner join People on Customer_roles.buyer_id = People.id
where
event_type ILIKE 'MEMBER_TABLET%' and
member_status IN ('moved','never answered', 'refused', 'complete')
group by
customer_id, member_status, events.event_type,
first_name, last_name, address, city,
state, phone, donator, zipcode, events.buyer_id
HAVING
MIN(events.created_at) between '2015-06-01' and '2015-08-01'
同样,如果排名机制不是 create_date,则将其更改为应有的值。
根据您的数据大小,您可能需要切换到max
分析。它不会调用order by
,因此应该是 O(n)。但是,请注意,如果您有两个相同的 create_date 值用于相同的 buy_id,这将产生两条记录而不是一条。您比我更了解您的数据,因此您可能可以评估这种风险与改进的性能:
with most_recent_address as (
select a.*, max(create_date) over (partition by buyer_id) as max_date
from addresses as a
)
Select
last_name, first_name, donator, customer_id,
phone, address, city, state, zipcode,
events.buyer_id
from events
join most_recent_address a on events.buyer_id = a.buyer_id and a.create_date = a.max_date
inner join customer_extras on addresses.buyer_id = customer_extras.buyer_id
inner join Customer_roles on events.buyer_id = Customer_roles.buyer_id
inner join People on Customer_roles.buyer_id = People.id
where
event_type ILIKE 'MEMBER_TABLET%' and
member_status IN ('moved','never answered', 'refused', 'complete')
group by
customer_id, member_status, events.event_type,
first_name, last_name, address, city,
state, phone, donator, zipcode, events.buyer_id
HAVING
MIN(events.created_at) between '2015-06-01' and '2015-08-01'
另外,你没有问这个,但你可能注意到我把你的两个条件从having
移到了where
子句。这应该有助于提高查询性能,因为您要在分组之前而不是之后消除行。仅当您将条件应用于分组函数时,Having
才是必需的(超过 where
)。由于排序/分组是数据库上最昂贵的操作之一,这对于大型数据集可能会产生很大的影响。
【讨论】:
如果它不起作用,请为您的表发布 DDL。你的努力听起来可行。 在您的设备上出现此错误?错误:缺少表“a”的 FROM 子句条目第 2 行:选择 a.*, row_number() over (partition by person_id orde... 好的,我会发布一些 ddl。我只是看到 a.* 给了麻烦。我不确定 a.* 实际上是什么意思。我看到 a.* 很多,但我从来没有使用过它。和*一样吗?我想这不是只是想知道。 我的错...我忘记将“地址”别名为 a。现在修复它。 Address People Events Customer_Roles Customer_Extras Buyer_id pk First_Name string created_at datetime donator string home_phone string Address1 string Last_Name string event_type string Customer_id string Buyer_id 唯一 id Address2 string Buyer_id 唯一 id Buyer_id 唯一 id Buyer_id 唯一 id 城市字符串 州字符串 邮政编码字符串 Updated_At 日期时间以上是关于表有重复数据,无法让两个聚合函数在 SQL Query 中工作的主要内容,如果未能解决你的问题,请参考以下文章