使用CASE比较SQL中的值,如果匹配则返回并退出CASE语句

时间:2015-11-13 14:29:08

标签: sql

人员表:

PersonID    Name
       1    David
       2    Victor

电话号码表:

PersonID    Phonetype   PhoneNumber
       1            7   7735821547
       1            6   7731245263
       1            5   7731426587
       1            4   7731243654
       1            8   7731241478
       1            2   7731423658
       1            1   7731427485
       2            1   7731547841

优先通过phonetype拉数:4然后6然后7然后5然后8然后2然后1

我想为每个人提取电话号码,但是当我使用左连接时,它会返回多个列。我只想为每个人准备一个号码。

输出应为:

PersonID    Name    PhoneNumber
       1    David   7731243654
       2    Victor  7731547841

2 个答案:

答案 0 :(得分:1)

我将使用postgres这个例子,我使用row_number()和cte,如果你有mySql将需要一个workaorund

您需要表优先级

CREATE TABLE priority
    ("PhoneType" int, "Priority" int)
;

INSERT INTO priority
    ("PhoneType", "Priority")
VALUES
    (7, 1),        (6, 2),
    (1, 3),        (2, 4),
    (3, 5),        (4, 6),
    (5, 7),        (8, 8),
    (9, 9)    ;

然后根据优先级将rownumber放入每个语音类型

WITH cte as (
    SELECT 
          p.*,
          pr."Priority",
          row_number() over (partition by "PersonID" ORDER BY "Priority") as rn
    FROM person p
    JOIN priority pr
      ON p."PhoneType" = pr."PhoneType"
    ORDER BY pr."Priority"
)
SELECT 
    c."PersonID",
    c."PhoneType", 
    c."PhoneNumber",
    CASE rn 
       WHEN 1 THEN 1
       ELSE NULL
    END as rn
FROM cte c

<强> SqlFiddle Demo

<强>输出

| PersonID | PhoneType | PhoneNumber |     rn |
|----------|-----------|-------------|--------|
|        1 |         7 |  7735487695 |      1 |
|        1 |         1 |  7731234569 | (null) |
|        1 |         5 |  7731547895 | (null) |

注意:我还更改了示例中的类型6 => 5,以突出显示优先级的工作方式

修改 SQL Server verion without table Fiddle

With Priority as (
    SELECT 7 as PhoneType,  1 as Priority UNION ALL
    SELECT 6 as PhoneType,  2 as Priority UNION ALL
    SELECT 1 as PhoneType,  3 as Priority UNION ALL
    SELECT 2 as PhoneType,  4 as Priority UNION ALL
    SELECT 3 as PhoneType,  5 as Priority UNION ALL
    SELECT 4 as PhoneType,  6 as Priority UNION ALL
    SELECT 5 as PhoneType,  7 as Priority UNION ALL
    SELECT 8 as PhoneType,  8 as Priority UNION ALL
    SELECT 9 as PhoneType,  9 as Priority 
), 
cte as (
    SELECT 
          p.*,
          pr.Priority,
          row_number() over (partition by PersonID ORDER BY Priority) as rn
    FROM Person p
    JOIN Priority pr
      ON p.PhoneType = pr.PhoneType    
)
SELECT 
    c.PersonID,
    c.PhoneType, 
    c.PhoneNumber
FROM cte c
WHERE rn = 1 

<强>输出

| PersonID | PhoneType | PhoneNumber |
|----------|-----------|-------------|
|        1 |         7 |  7735821547 |
|        2 |         1 |  7731547841 |

答案 1 :(得分:0)

你有太多的WHEN陈述。如果您只想为值7做一些事情,那么您应该只有一个WHEN语句:

CASE 
WHEN PhoneType = 7 and PhoneNbr is not null THEN 1 
ELSE NULL
END AS RN