如何在保留重复行的同时消除三重行(SQL server 2016)

时间:2017-09-26 12:04:09

标签: sql sql-server group-by duplicates

我想小心地提出我想要回答的问题,而不是试图将其提炼到这个过程的一个步骤,所以请忍受我的“意识流”风格。我提出的问题是标题建议“我如何在保留重复行的同时消除重复行(所以没有分组)?”但我会接受在流程的任何一步都可以得到的答案我想要。使用SQL Server 2016。

我正在尝试在我们的数据库中找到“零账单通话”。我使用的第一个定义是这段代码

SELECT  

     max([Inbound Call Client Account]) as [account]

      ,convert(date,format(Dateadd(hh,1,[Inbound Call Time]),'dd/MM/yyyy'),103) as [Date]

     ,max([Activation Id]) as [Activation Id]

  FROM [Call_Table]

  where 

  convert(date,format(Dateadd(hh,1,[Inbound Call Time]),'dd/MM/yyyy'),103) >= '2017-09-01'

  and [Chargeable Duration] = 0

  and ([Inbound Connected Call Duration] IS NULL or [Inbound Connected Call Duration] <1)

  and [Inbound Call Type] = 'normal operator call'

  group by [Inbound Call Time]

基本上任何已接听的呼叫(正常的话务员呼叫),持续时间为零(或最小)。我按入站呼叫时间分组,因为每个符合定义的呼叫都有两行,我想在SSRS报告中进行计数,所以我只想要每次呼叫一行。

这确定了我想要的电话,但它也带回了我不想要的电话。

account   Date             Activation Id
310722  06/09/2017  15CD7A85-084D-4276-BC80-B5369710EC28
310722  06/09/2017  AA145DE5-A278-4181-8EEF-0AFC4B38F2A8
310722  06/09/2017  71413B46-CDC8-41A2-AD3D-2CE88B7C851F
...
310722  14/09/2017  F36E147A-AC39-4441-9472-225FFD56E013
310722  14/09/2017  04372920-DDC4-47DC-8D9E-1E807441CDB3

我知道(从之前的工作中)14号电话是真正的0计费,而6号电话则不是。所以我研究了它的不同之处。

SELECT 
      [Inbound Call Client Account]

      ,[Inbound Call Type]


      ,[Chargeable Duration]
      ,[Activation Id]

      ,[Inbound Call Time]

  FROM [Call_Table]

  where [activation id] = '15CD7A85-084D-4276-BC80-B5369710EC28'

  or [activation id] = 'F36E147A-AC39-4441-9472-225FFD56E013'

  or [activation id] = 'AA145DE5-A278-4181-8EEF-0AFC4B38F2A8'

  or [activation id] = '04372920-DDC4-47DC-8D9E-1E807441CDB3' 

  or [activation id] = '71413B46-CDC8-41A2-AD3D-2CE88B7C851F'

生成

output

明显的区别特征(对我来说)是误报有3行数据,具有相同的激活ID。有没有办法将这种区别合并到我的原始查询中,以便不再出现这些区别?但是14日的真正积极因素有重复的行,所以据我所知,一个小组将无法工作。

2 个答案:

答案 0 :(得分:0)

我认为使用HAVING将是最简单的方法。但为此你应该使用GROUP BY这个查询对你有帮助吗?

SELECT  

     max([Inbound Call Client Account]) as [account]

      ,convert(date,format(Dateadd(hh,1,[Inbound Call Time]),'dd/MM/yyyy'),103) as [Date]

     ,max([Activation Id]) as [Activation Id]

  FROM [Call_Table]

  where 

  convert(date,format(Dateadd(hh,1,[Inbound Call Time]),'dd/MM/yyyy'),103) >= '2017-09-01'

  and [Chargeable Duration] = 0

  and ([Inbound Connected Call Duration] IS NULL or [Inbound Connected Call Duration] <1)

  and [Inbound Call Type] = 'normal operator call'

  group by [Inbound Call Time],[Activation Id]
  HAVING Count([Activation Id]) < 3

答案 1 :(得分:0)

您正在寻找的答案是over clause。同样在未来的开发中,尝试以列1字为例。 [Inbound Call Client Account]会变成Inbound_Call_Client_Account。这样可以更容易地引用列。底部查询将为您提供仅一式三份的所有行,您可以从那里执行任何CRUD操作。

SELECT * FROM (
SELECT [Inbound Call Client Account] as [account]
,convert(date,format(Dateadd(hh,1,[Inbound Call Time]),'dd/MM/yyyy'),103) as [Date]
,ROW_NUMBER() OVER(PARTITION BY [Activation Id] ORDER BY [Inbound Call Time] DESC) AS "Row_Number"
  FROM [Call_Table]
      where 
      convert(date,format(Dateadd(hh,1,[Inbound Call Time]),'dd/MM/yyyy'),103) >= '2017-09-01'
      and [Chargeable Duration] = 0
      and ([Inbound Connected Call Duration] IS NULL or [Inbound Connected Call Duration] <1)
      and [Inbound Call Type] = 'normal operator call') AS foo
WHERE foo.row_number = 3