2013-07-30 44 views
0

我试图在Mysql中使用CASE语句,虽然MySQL不会抱怨我的查询,但它无法提供正确的结果。为什么MySQL Switch-Case没有选择正确的值?

什么我试图做的是等价的:

if value < 20 then 1 
elseif value < 30 then 2 
elseif value < 40 then 3 
. 
. 
. 
else value < 90 then 45 

,这是我的MySQL声明:

SELECT 
    UM.DA, 
    UM.PA, 
    IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) AS "PS", 
CASE 
    WHEN "PS" < 20 THEN 1 
    WHEN "PS" < 30 THEN 2 
    WHEN "PS" < 40 THEN 3 
    WHEN "PS" < 50 THEN 5 
    WHEN "PS" < 60 THEN 8 
    WHEN "PS" < 70 THEN 12 
    WHEN "PS" < 80 THEN 20 
    WHEN "PS" < 90 THEN 30 
    WHEN "PS" >= 90 THEN 45 
END AS "Points", 
FROM 
    Table1 UM 

,这是我的结果集:

+-------+-------+--------+--------+ 
| UM.DA | UM.PA | PS | Points | 
+-------+-------+--------+--------+ 
| 19.21 | 18.39 | 18.39 | 1 | 
+-------+-------+--------+--------+ 
| 24.80 | 34.91 | 34.91 | 1 | 
+-------+-------+--------+--------+ 
| 29.72 | 35.89 | 35.89 | 1 | 
+-------+-------+--------+--------+ 

这就是我的结果应该如何:

+-------+-------+--------+--------+ 
| UM.DA | UM.PA | PS | Points | 
+-------+-------+--------+--------+ 
| 19.21 | 18.39 | 18.39 | 1 | 
+-------+-------+--------+--------+ 
| 24.80 | 34.91 | 34.91 | 3 | 
+-------+-------+--------+--------+ 
| 29.72 | 35.89 | 35.89 | 3 | 
+-------+-------+--------+--------+ 

那么,什么是在MySQL查询中使用“CASE”(这是一个查询,而不是存储过程)

另外,在性能方面是它更好地把这种逻辑在SQL的正确方法查询,还是应该用我选择的编程语言过滤结果?

谢谢!

+0

为什么你在包含PS的时候在Case-When语句中使用双引号?这是一个专栏名称。 –

+0

因为MySQL的抱怨,如果我不 – ILikeTacos

回答

2

尝试这种情况:

SELECT DA, PA, PS, 
     CASE 
      WHEN PS < 20 THEN 1 
      WHEN PS < 30 THEN 2 
      WHEN PS < 40 THEN 3 
      WHEN PS < 50 THEN 5 
      WHEN PS < 60 THEN 8 
      WHEN PS < 70 THEN 12 
      WHEN PS < 80 THEN 20 
      WHEN PS < 90 THEN 30 
      ELSE 45 
     END AS "Points" 
FROM (SELECT DA, PA, 
      IF((DA - PA) > 25, DA, PA) AS PS 
     FROM Table1 UM) temp 

它移动PS计算为子查询,因此它可以在CASE表达而不重复所述计算被引用。而PS必须是名称,而不是字符串。

+0

我的MySQL版本抱怨,如果我不删除引号,它返回“未知列PS在字段列表中“ – ILikeTacos

+0

这是因为您不能在定义的同一个SELECT列表中引用别名。这就是为什么我在我的答案中将其转移到子查询中的原因。 – Barmar

+0

你应该在这里使用反引号'UM.DA',否则它会被认为是表格和列 –

0

"PS"只是一个字符串。它不是你创建的别名,所以你将一个字符串与一个整数进行比较,并且mysql会自动将该字符串转换为一个int,使其为0,因此所有的情况都匹配。你想

CASE 
    WHEN PS < 20 THEN 1 
     ^^---note lack of quotes 
+0

你不能引用别名在同一选择 – Bohemian

+0

是的,那也... –

0

我不认为你可以使用一个别名的查询内的列,除非它是ORDER BY子句。因此(特别是由于语音标记的别名而不是反引号),您正在进行字符串比较。查询更改为:

SELECT 
    UM.DA, 
    UM.PA, 
    IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) AS "PS", 
CASE 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 20 THEN 1 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 30 THEN 2 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 40 THEN 3 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 50 THEN 5 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 60 THEN 8 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 70 THEN 12 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 80 THEN 20 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 90 THEN 30 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) >= 90 THEN 45 
END AS "Points", 
FROM 
    Table1 UM 
相关问题