Select 语句中的案例

Posted

技术标签:

【中文标题】Select 语句中的案例【英文标题】:Case in Select Statement 【发布时间】:2012-12-20 18:50:09 【问题描述】:

我有一条 SQL 语句,其中包含来自 SELECTCASE,但我无法正确处理。你们能不能给我看一个CASE 的例子,其中案例是条件,结果来自案例。例如:

     Select xxx, yyy
     case : desc case when bbb then 'blackberry';
     when sss then 'samsung';
     end 
     from (select ???? .....

结果显示在哪里

 name                         age       handphone
xxx1                         yyy1      blackberry
xxx2                         yyy2      blackberry

【问题讨论】:

My answer 解释两种案例类型 1. 简单的 CASE 表达式 2. 搜索的 CASE 表达式。以及两种类型在 SELECT、UPDATE、With ORDER BY、With HAVING 查询中的案例用法。 【参考方案1】:

对于此类有关语法和用法的问题,MSDN 是一个很好的参考。这来自 Transact SQL 参考 - CASE 页面。

http://msdn.microsoft.com/en-us/library/ms181765.aspx

USE AdventureWorks2012;
GO
SELECT   ProductNumber, Name, "Price Range" = 
  CASE 
     WHEN ListPrice =  0 THEN 'Mfg item - not for resale'
     WHEN ListPrice < 50 THEN 'Under $50'
     WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250'
     WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000'
     ELSE 'Over $1000'
  END
FROM Production.Product
ORDER BY ProductNumber ;
GO

如果您正在使用 SQL Server,您可能想要查看的另一个好站点是SQL Server Central。这为您想学习的 SQL Server 的任何领域提供了大量资源。

【讨论】:

由于每个case 条件都按指定的顺序检查并且第一个true 条件获胜,因此无需执行重复检查,例如WHEN ListPrice &gt;= 50 and ListPrice &lt; 250 THEN 可以写成 WHEN ListPrice &lt; 250 THEN,因为前一行已经确定 ListPrice 不是 &lt; 50。 (就像您处理 &lt; 50 而不再次检查 0 一样。)此外:负标价将落入 'Under $50' 存储桶。【参考方案2】:

我认为这些可能对您有所帮助。

使用带有简单 CASE 表达式的 SELECT 语句

SELECT 语句中,简单的CASE 表达式只允许进行相等检查;没有进行其他比较。以下示例使用CASE 表达式更改产品线类别的显示,使其更易于理解。

USE AdventureWorks2012;
GO
SELECT   ProductNumber, Category =
      CASE ProductLine
         WHEN 'R' THEN 'Road'
         WHEN 'M' THEN 'Mountain'
         WHEN 'T' THEN 'Touring'
         WHEN 'S' THEN 'Other sale items'
         ELSE 'Not for sale'
      END,
   Name
FROM Production.Product
ORDER BY ProductNumber;
GO

使用带有搜索到的CASE 表达式的SELECT 语句

SELECT 语句中,搜索到的CASE 表达式允许根据比较值替换结果集中的值。以下示例根据产品的价格范围将标价显示为文本注释。

USE AdventureWorks2012;
GO
SELECT   ProductNumber, Name, "Price Range" = 
      CASE 
         WHEN ListPrice =  0 THEN 'Mfg item - not for resale'
         WHEN ListPrice < 50 THEN 'Under $50'
         WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250'
         WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000'
         ELSE 'Over $1000'
      END
FROM Production.Product
ORDER BY ProductNumber ;
GO

ORDER BY 子句中使用CASE

以下示例使用ORDER BY 子句中的CASE 表达式根据给定的列值确定行的排序顺序。在第一个示例中,计算 HumanResources.Employee 表的 SalariedFlag 列中的值。将 SalariedFlag 设置为 1 的员工按 BusinessEntityID 的降序顺序返回。将 SalariedFlag 设置为 0 的员工按 BusinessEntityID 的升序顺序返回。在第二个示例中,当 CountryRegionName 列等于“United States”时,结果集按 TerritoryName 列排序,所有其他行按 CountryRegionName 排序。

SELECT BusinessEntityID, SalariedFlag
FROM HumanResources.Employee
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
        ,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END;
GO


SELECT BusinessEntityID, LastName, TerritoryName, CountryRegionName
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL
ORDER BY CASE CountryRegionName WHEN 'United States' THEN TerritoryName
         ELSE CountryRegionName END;

UPDATE 语句中使用CASE

以下示例在UPDATE 语句中使用CASE 表达式来确定为将SalriedFlag 设置为0 的员工的VacationHours 列设置的值。从VacationHours 中减去10 小时会得到负值,VacationHours增加40小时;否则,VacationHours 增加 20 小时。 OUTPUT 子句用于显示假期前后的值。

USE AdventureWorks2012;
GO
UPDATE HumanResources.Employee
SET VacationHours = 
    ( CASE
         WHEN ((VacationHours - 10.00) < 0) THEN VacationHours + 40
         ELSE (VacationHours + 20.00)
       END
    )
OUTPUT Deleted.BusinessEntityID, Deleted.VacationHours AS BeforeValue, 
       Inserted.VacationHours AS AfterValue
WHERE SalariedFlag = 0; 

HAVING 子句中使用CASE

以下示例在HAVING 子句中使用CASE 表达式来限制SELECT 语句返回的行。该语句返回 HumanResources.Employee 表中每个职位的最大小时费率。 HAVING 条款将头衔限制为最高工资高于 40 美元的男性或最高工资高于 42 美元的女性持有的头衔。

USE AdventureWorks2012;
GO
SELECT JobTitle, MAX(ph1.Rate)AS MaximumRate
FROM HumanResources.Employee AS e
JOIN HumanResources.EmployeePayHistory AS ph1 ON e.BusinessEntityID = ph1.BusinessEntityID
GROUP BY JobTitle
HAVING (MAX(CASE WHEN Gender = 'M' 
        THEN ph1.Rate 
        ELSE NULL END) > 40.00
     OR MAX(CASE WHEN Gender  = 'F' 
        THEN ph1.Rate  
        ELSE NULL END) > 42.00)
ORDER BY MaximumRate DESC;

有关这些示例的详细说明,请访问source。

另请访问here 和here 了解详细示例。

【讨论】:

非常感谢这么详细的回答。【参考方案3】:

你也可以使用:

SELECT CASE
         WHEN upper(t.name) like 'P%' THEN
          'productive'
         WHEN upper(t.name) like 'T%' THEN
          'test'
         WHEN upper(t.name) like 'D%' THEN
          'development'
         ELSE
          'unknown'
       END as type
FROM table t

【讨论】:

以上是关于Select 语句中的案例的主要内容,如果未能解决你的问题,请参考以下文章

选择语句问题中的案例?

linux12shell编程 --> 流程控制之select语句

如果参数为空,则在 where 语句中的 TSQL 案例

Oracle SQL:案例语句

是否有任何规则可以在条件/案例表达式中使用sql语句子句的哪一部分?

数据库子查询-select后面语句