Case or If,在 SQL 中选择啥

Posted

技术标签:

【中文标题】Case or If,在 SQL 中选择啥【英文标题】:Case or If, What to choose in SQLCase or If,在 SQL 中选择什么 【发布时间】:2012-02-29 13:40:53 【问题描述】:

我如何管理这个查询。我希望查询中只有一个人。如果 empId 列中有 id,则为他的姓名。否则就是老板的名字。

Product empId   teamId  
----------------------
A       1       3
B       2       4
C               3
D       2       3
E               4

User Table
Id  Name
-----------
1   Jim
2   Carrey
3   Bill
4   Clinton

Team Table
Team_Id BossId
-----------
3   3
4   4    

结果应该是这样的:

Product user.name
-----------------
A       Jim
B       Carrey
C       Bill
D       Carrey
E       Clinton

【问题讨论】:

【参考方案1】:

使用CASECOALESCE() 函数:

SELECT 
    x.Product
  , COALESCE(emp.Name, boss.Name) AS Name
FROM
    TableX AS x
  LEFT JOIN
    User AS emp
      ON emp.Id = x.empId
  LEFT JOIN
    User AS boss
      ON boss.Id = x.bossId

更新:

SELECT 
    x.Product
  , COALESCE(emp.Name, boss.Name) AS Name
FROM
    TableX AS x
  LEFT JOIN
    User AS emp
      ON emp.Id = x.empId
  LEFT JOIN
      Team As t
    JOIN
      User AS boss
        ON boss.Id = t.bossId
      ON t.team_Id = x.teamId

【讨论】:

打败我。同样重要的是要注意,LEFT JOIN 只会在存在使 COALESCE 工作的信息时才将其带入。如果您使用 INNER/RIGHT JOIN,这将无法正常工作。 @ypercube 感谢您的帮助。我意识到中间还有一个 TEM 表。只为老板。你能更新你的解决方案吗 @ypercube 使用 Coalesce,查询变得更短更清晰。谢谢。【参考方案2】:

类似这样的:

SELECT
    Table1.Product,
    CASE 
        WHEN Table1.empId IS NULL
        THEN Boss.name
        ELSE Emp.name
    END
FROM
    Table1
    LEFT JOIN [User] AS Emp
        ON Emp.Id =Table1.empId
    LEFT JOIN Team
        ON Team.Team_Id =Table1.teamId
    LEFT JOIN [User] AS Boss
        ON Boss.Id=Team.BossId

【讨论】:

感谢您的帮助。要求有一点变化。你能更新你的解决方案吗? 非常感谢。很难选择一个。 (ypercube 或你。)我选择了较短的。【参考方案3】:
SELECT Y.Product, U.Name
  FROM YourTable AS Y 
       JOIN Users AS U ON Y.empId = U.Id
UNION
SELECT Y.Product, U.Name
  FROM YourTable AS Y 
       JOIN Team AS T ON Y.teamId = T.Team_Id
       JOIN Users AS U ON T.BossId = U.Id
 WHERE Y.empId IS NULL;

【讨论】:

【参考方案4】:
-- SET search_path='tmp';
DROP TABLE tmp.products;
CREATE TABLE products
        ( product CHAR(1)
        , emp_id INTEGER
        , team_id INTEGER
        );
INSERT INTO products(product,emp_id,team_id)
     VALUES ('A',1,3),  ('B',2,4),  ('C',NULL,3),  ('D',2,3),  ('E',NULL,4);
DROP TABLE tmp.names;
CREATE TABLE names
        (id INTEGER
        , zname varchar
        );
INSERT INTO names(id,zname)
     VALUES ( 1, 'Jim') ,( 2, 'Carrey') ,( 3, 'Bill') ,( 4, 'Clinton') ;

DROP TABLE tmp.teams;
CREATE TABLE teams
        ( team_id INTEGER NOT NULL
        , boss_id INTEGER NOT NULL
        );
INSERT INTO teams(team_id,boss_id) VALUES ( 3,4) , (4,4);


WITH lutser(prod,id,team) AS
        (
        SELECT k1.product AS prod
                , k1.emp_id AS id
                , k1.team_id AS team
        FROM tmp.products k1
        UNION
        SELECT k2.product AS prod
                , t.boss_id AS id
                , k2.team_id AS team
        FROM tmp.products k2
        JOIN tmp.teams t ON t.team_id = k2.team_id
        WHERE k2.emp_id IS NULL
        )
SELECT l.prod
        , l.id
        , l.team
        , n.zname
FROM lutser l
JOIN names n ON n.id = l.id
        ;

此 CTE 递归版本的额外奖励点...

【讨论】:

以上是关于Case or If,在 SQL 中选择啥的主要内容,如果未能解决你的问题,请参考以下文章

VB中CASE和IF有啥不同?

SQL Server 2008 - SELECT 子句中的 Case / If 语句 [重复]

为啥在 Oracle 中使用 CASE 进行子选择比 JOIN WITH OR 更快

SQL里if语句和case语句有啥区别吗?哪个使用更高效?就是查询更优化?

CASE SQL Oracle 查询 - 出了啥问题?

选择结构有啥特点?C语言实现选择结构有哪几种方式