![](/img/trans.png)
[英]How to filter records based on minimum date and some other criteria where each transaction can have multiple dates in SQL?
[英]SQL: Filter records based on record creation date and other criteria
我正在努力寻找一种更好的解决方案,以从用户呼叫数据表中选择唯一记录。 我的表结构如下:
SELECT [MarketName],
[WebsiteName] ,
[ID] ,
[UserID],
[CreationDate],
[CallDuration],
[FromPhone] ,
[ToPhone],
[IsAnswered],
[Source]
FROM [dbo].[UserCallData]
该表中有多个条目,它们具有不同且相同的ID。 我想检查[FromPhone]和[ToPhone]在过去3个月中是否存在多次,如果是,我想根据[CreationDate]来选择所有列的第一条记录,将出现的次数计为TotalCallCount并求和totalCallDuration作为单个记录。 如果[FromPhone]和[ToPhone]没有多次出现,我想这样选择所有列。 我已经能够提出如下部分查询。 但这不会返回所有列而不包括group by子句,也不满足我的整个条件。 任何帮助,将不胜感激。
select [FromPhone],
MIN([CreationDate]),
[ToPhone],
marketname,
count(*) as TotalCallCount ,
sum(CallDuration) as TotalCallDuration
from [dbo].[UserCallData]
where [CreationDate] >= DATEADD(MONTH, -3, GETDATE())
group by [FromPhone],[ToPhone], marketname
having count([FromPhone]) > 1 and count([ToPhone]) >1
尝试使用ROW_NUMBER()
;with cte as
(
select *, ROW_NUMBER() OVER(PARTITION BY FromPhone, ToPhone ORDER BY CreationDate) as RN
from UserCallData
where CreationDate >= DATEADD(MONTH, -3, GETDATE())
),
cte_totals as
(
select C1.FromPhone, C1.ToPhone, COUNT(*) as TotalCallCount, SUM(CallDuration) as TotalCallDuration
from cte C1
where exists(select * from cte C2 where C1.FromPhone = C2.FromPhone and C1.ToPhone = C2.ToPhone and C2.RN > 1)
group by C1.FromPhone, C1.ToPhone
)
select C1.*, TotalCallCount, TotalCallDuration
from cte C1
inner join cte_totals C2 on C1.FromPhone = C2.FromPhone and C1.ToPhone = C2.ToPhone
where C1.RN = 1
我在此处直接编写了查询,因此它可能会有一些错误或类型错误,但主要思想可能很清楚。
我不完全确定我已经理解了这个问题,但是如果我有以下内容,可能就是您想要的(或者是一个有用的起点):
SELECT
ucd.FromPhone,
min(ucd.CreationDate) as MinCreationDate,
ucd.ToPhone,
ucd.MarketName,
count(*) as TotalCallCount,
sum(ucd.CallDuration) as TotalCallDuration,
case
when min(ucd.WebsiteName) = max(ucd.WebsiteName) then min(ucd.WebsiteName)
else '* Various'
end as WebsiteName,
case
when min(ucd.ID) = max(ucd.ID) then min(ucd.ID)
else '* Various'
end as ID,
case
when min(ucd.UserID) = max(ucd.UserID) then min(ucd.UserID)
else '* Various'
end as UserID,
case
when min(ucd.IsAnswered) = max(ucd.IsAnswered) then min(ucd.IsAnswered)
else '* Some'
end as IsAnswered,
case
when min(ucd.Source) = max(ucd.Source) then min(ucd.Source)
else '* Various'
end as Source
FROM
dbo.UserCallData ucd
WHERE
ucd.CreationDate >= DATEADD(MONTH, -3, GETDATE())
GROUP BY
ucd.FromPhone,
ucd.ToPhone,
ucd.MarketName
在将行折叠在一起的情况下,如果所有行都在给定列上一致(所以min(Field) = max(Field)
),我将返回min(Field)
值(所有其他值都相同,但避免出现问题)需要其他会干扰其他情况的“分组依据”子句)。 在他们不同意的地方,我返回了"* something"
。
该代码假定所有列都是文本类型的列(您尚未说过),您可能会遇到转换错误。 它还假定这些字段都不为null
。 如果这些假设不正确,您/我们可以修改代码。 如果您无法自己做到这一点,请告诉我有关问题,我们将竭尽所能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.