使用GROUP或RANK中的WHERE的SQL语句(第2部分)

时间:2013-02-04 21:58:28

标签: sql sum grouping where

我最近在这里发布了一个关于SQL Where Statement / Grouping的问题:

SQL statement using WHERE from a GROUP or RANK

现在我有一些跟进。

与上一个问题类似,我们假设我有一个35,000行的表,其中包含以下列:

销售代表|父帐户ID |帐户ID |合同总价值|日期

每行都是帐户ID,但多个帐户ID可以归属于父帐户ID。

与第一个问题的回答类似,这可能是一张桌子。首先,所有内容都必须按销售代表进行分组。从中,所有内容都需要按父帐户ID进行分组,其中所有帐户的分组总合同价值> 10,000。然后,所有内容都将按父帐户ID的总TCV显示和排名,我需要代理商排名前35位的父帐户ID。

所以前几行数据可能如下所示:

Sales Rep | Parent Account ID| Account ID | Total Contract Value | Date      | Rank
John Doe  | ParentABC12345   | ABC425     | 5,000                | 1/2/2013  |1
John Doe  | ParentABC12345   | ABC426     | 10,000               | 1/2/2013  |1
John Doe  | ParentDJE12345   | DJE523     | 11,000               | 1/2/2013  |2
John Doe  | ParentFBC12345   | FBC6723    | 4,000                | 1/2/2013  |3
John Doe  | ParentFBC12345   | FBC6727    | 4,000                | 1/2/2013  |3

请注意排名如何根据父帐户ID运作。帐户ID DJE523具有单个最大的TCV,但它在父母帐户ID ParentABC12345的分组值较大的情况下排名第二b / c。因此,将有35个父帐户ID的排名,但在该排名中,他们可以说100多行实际数据。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

总是很乐意跟进。 “父级别”将添加为INNER JOIN

编辑:正如Dan Bracuk正确提到的,my first answer不正确。我更改了查询以满足正确的条件。我还将时间跨度应用于父帐户。

DECLARE @minimumValue decimal(20,2) = 10000
DECLARE @numberOfAccounts int = 35
DECLARE @from datetime = '1/1/2013'
DECLARE @till datetime = DATEADD(MONTH, 1, @from)

SELECT 
  [sub].[Sales Rep],
  [sub].[Rank],
  [sub].[Account ID],
  [sub].[Total Contract Value],
  [sub].[Parent Account ID],
  [sub].[Total],
  [sub].[ParentRank]
FROM
(
  SELECT
    [s].[Sales Rep],
    [s].[Account ID],
    [s].[Total Contract Value],
    DENSE_RANK() OVER (PARTITION BY [s].[Sales Rep] ORDER BY [s].[Total Contract Value] DESC) AS [Rank],
    [p].[Parent Account ID],
    [p].[Total],
    [p].[ParentRank]
  FROM [Sales] [s]
  INNER JOIN 
  (
    SELECT
      [Parent Account ID],
      SUM([Total Contract Value]) AS [Total],
      RANK() OVER(ORDER BY SUM([Total Contract Value]) DESC) AS [ParentRank]
    FROM [Sales]
    WHERE[Date] > @from AND [Date] < @till
    GROUP BY [Parent Account ID]
    HAVING SUM([Total Contract Value]) > @minimumValue
  ) AS [p] ON [s].[Parent Account ID] = [p].[Parent Account ID]
  WHERE [Date] > @from AND [Date] < @till
) AS [sub]
WHERE [sub].[Rank] <= @numberOfAccounts
ORDER BY 
  [Sales Rep] ASC,
  [ParentRank] ASC,
  [Rank] ASC

And here is a new Fiddle

答案 1 :(得分:-1)

如果您使用的是SQL Server,我认为这样可以帮到您:

Select top 35 
    SalesRep, 
    ParentAccountId, 
    sum(TotalContractValue)  from Table
group by SalesRep, ParentAccountId 
order by sum(TotalContractValue) desc