SQL返回值优先级

时间:2013-10-25 19:08:27

标签: sql sql-server

我正在尝试构建一个SQL Server查询,在该查询中,它会查看一组包含数百万行的表,如果它不存在则返回最近的值。

假设我们有这张表:

id | phone_number  | status   | create_date  
---|-------------- | -------- | ---------------  
1  | 123-123-1234  | ANSWER   | xxx  
2  | 123-123-1234  | MACHINE  | xxx  
3  | 123-123-1234  | HANGUP   | xxx  
4  | 123-123-1234  | CALLBACK | xxx  

每笔交易都是一行。

我需要查找特定日期范围内的所有数字,如果phone_number在一组值中具有某些状态,则返回该id,如果不返回最新的id。但每个phone_number只有一条记录

我知道语法错误,但我想会更好地解释我的想法。

SELECT * FROM transactions t
WHERE create_date = '2013-10-10' AND
(id = (
  SELECT MAX(id) FROM transactions
  WHERE t.phone_number = phone_number AND status IN ('ANSWER','CALLBACK')
) OR (
  SELECT MAX(id) FROM transactions
  WHERE t.phone_number = phone_number
) 

如果在该时间范围内存在ANSWER状态,则从该号码返回具有该状态的最新ID,如果不存在,则返回CALLBACK(如果不是任何其他状态)。这适用于所有phone_numbers。

我希望结果是这样的:

id | phone_number | status   | create_date  
-- | ------------ | -------- | ----------  
1  | 123-123-1234 | ANSWER   | xxx  
20 | 321-321-3210 | HANGUP   | xxx  
30 | 123-312-2310 | CALLBACK | xxx  

...

谢谢!

1 个答案:

答案 0 :(得分:2)

也许这就是你想要做的事情:

;WITH x AS (SELECT id, phone_number, status, create_date,
  rn = ROW_NUMBER() OVER 
  (
    PARTITION BY phone_number 
    ORDER BY CASE [status]
      WHEN 'ANSWER' THEN 1
      WHEN 'CALLBACK' THEN 2 ELSE 3
    END, create_date)
  FROM dbo.yourtable
)
SELECT id, phone_number, status, create_date FROM x WHERE rn = 1;

SQLfiddle demo