带有多个WHERE子句的SQL RANK

时间:2015-05-18 13:17:14

标签: sql tsql select

我的销售办公室很少,还有他们的销售。我正在尝试设置报告,基本上会说明每个办公室的表现如何。得到一些SUM,COUNTs很容易,但我正在努力获得单一职位的排名。

我希望此查询在整个期间和/或指定时间内返回单个办公室的级别(例如,BETWEEN'2015-01-01'和'2015-01-15')

我还需要从排名列表中排除一些办公室(例如OfficeName NOT IN('GGG','QQQ')),因此使用样本数据,办公室'XYZ'的排名将为5。

如果OfficeName ='XYZ'包含在WHERE子句中,则RANK显然会= 1,因为SQL会在执行其余代码之前过滤掉WHERE子句中未包含的其他行。 有没有办法做同样的事情,而不使用TemporaryTable?

SELECT OfficeName, SUM(Value) as SUM,
RANK() OVER (ORDER BY SUM(VALUE) DESC) AS Rank

FROM Transactions t
JOIN Office o ON t.TransID=o.ID

WHERE OfficeName NOT IN ('GGG','QQQ')
--AND OfficeName = 'XYZ' 

GROUP BY OfficeName

ORDER BY 2 DESC; 

我正在使用MS SQL server 2008。

SQL提供了一些随机数据:http://sqlfiddle.com/#!3/fac7a/35

非常感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

如果我理解你想要做的话:

SELECT * 
FROM (
  SELECT OfficeName, SUM(Value) as SUM,
    RANK() OVER (ORDER BY SUM(VALUE) DESC) AS Rank    
  FROM Transactions t
  JOIN Office o ON t.TransID=o.ID
  WHERE OfficeName NOT IN ('GGG','QQQ')
  GROUP BY OfficeName
) dat
WHERE OfficeName = 'XYZ'; 

答案 1 :(得分:0)

您只需将代码包装为派生表或使用CTE这样的代码,然后为OfficeName = 'XYZ'执行过滤。

;WITH CTE AS 
(
SELECT OfficeName, SUM(Value) as SUM,
RANK() OVER (ORDER BY SUM(VALUE) DESC) AS Rank
FROM Transactions t
JOIN Office o ON t.TransID=o.ID
WHERE OfficeName NOT IN ('GGG','QQQ')
GROUP BY OfficeName
)
SELECT * 
FROM CTE
WHERE OfficeName = 'XYZ';

答案 2 :(得分:0)

如果没有子查询,这是一种有趣的方法:

SELECT TOP 1 OfficeName, SUM(Value) as SUM,
       RANK() OVER (ORDER BY SUM(VALUE) DESC) AS Rank
FROM Transactions t JOIN
     Office o
     ON t.TransID = o.ID
WHERE OfficeName NOT IN ('GGG','QQQ')
GROUP BY OfficeName
ORDER BY (CASE WHEN OfficeName = 'XYZ' THEN 1 ELSE 2 END);