2016-11-15 82 views
2

使用变量我有这个疑问的case语句MySQL的

select 
count(so.shop_order_id), 
case 
    when so.subtotal_amount < 99.99 then 'under 100' 
    when so.subtotal_amount between 100.00 and 149.99 then '100-149' 
    when so.subtotal_amount between 150.00 and 249.99 then '150-249' 
    when so.subtotal_amount between 250.00 and 399.99 then '250-399' 
    when so.subtotal_amount between 400.00 and 499.99 then '400-499' 
    when so.subtotal_amount > 500 then '500+' 
end 

from shop_order so 

where so.created_at between '2015-11-29 23:59:59' and '2015-11-31 00:00:01' 
and (case 
    when so.subtotal_amount < 99.99 then 'under 100' 
    when so.subtotal_amount between 100.00 and 149.99 then '100-149' 
    when so.subtotal_amount between 150.00 and 249.99 then '150-249' 
    when so.subtotal_amount between 250.00 and 399.99 then '250-399' 
    when so.subtotal_amount between 400.00 and 499.99 then '400-499' 
    when so.subtotal_amount > 500 then '500+' 
end) is not null 

group by (case 
    when so.subtotal_amount < 99.99 then 'under 100' 
    when so.subtotal_amount between 100.00 and 149.99 then '100-149' 
    when so.subtotal_amount between 150.00 and 249.99 then '150-249' 
    when so.subtotal_amount between 250.00 and 399.99 then '250-399' 
    when so.subtotal_amount between 400.00 and 499.99 then '400-499' 
    when so.subtotal_amount > 500 then '500+' 
end) 

它很适合我,但我想知道是否有一种方法可以不必重复case语句。我可以设置变量或使用别名或其他东西来代替它吗?每次进行调整时,我都必须编辑案例陈述的每个实例。我对任何事情都很开放。谢谢。

+2

使用MySQL,您可以在GROUP BY中使用SELECT表达式中的别名,但不能在WHERE中使用别名;但是在那个地方使用CASE时,只需做'AND so.subtotal_amount IS NOT NULL'(因为它是唯一的方法,不用担心像99.999那样的值,CASE可能会导致null)_,或者添加' HAVINGAlias IS NOT NULL'到查询中。 ......实际上,在subtotal_amount = 500的逻辑中你有一个“漏洞”。 – Uueerdo

+0

非常好的反馈。谢谢! – Bartonb12

回答

1

这是什么@Uueerdo在评论中写道实施。

在SELECT子句中使用表达式的别名(as range)。 GROUP BY使用该别名group by range。如果so.subtotal_amount IS NULL表达式只能为NULL,那么您可以在WHERE子句中使用此条件。

你的表情也可以缩短。如果第一个条件(subtotal_amount < 100)失败,那么很明显subtotal_amount>= 100,因此您不需要BETWEEN语句。请注意,BETWEEN在MySQL中意味着“包含”。 x BETWEEN a and bx >= a and x <= b相同。

此外 - 当你说“100以下”时,你应该使用< 100而不是< 99.99。 '500+'相同 - 应该是>= 500。所以你在你的范围内没有任何差距。

select 
    count(so.shop_order_id), 
    case 
     when so.subtotal_amount < 100 then 'under 100' 
     when so.subtotal_amount < 150 then '100-149' 
     when so.subtotal_amount < 250 then '150-249' 
     when so.subtotal_amount < 400 then '250-399' 
     when so.subtotal_amount < 500 then '400-499' 
     when so.subtotal_amount >= 500 then '500+' 
    end as range 
from shop_order so 
where so.created_at between '2015-11-29 23:59:59' and '2015-11-31 00:00:01' 
    and so.subtotal_amount is not null 
group by range 
+0

这看起来很棒。感谢您的解释并花时间浏览一下。这一定会在未来为我节省一些时间。 – Bartonb12

1

您可以使用子查询:

select count(so.shop_order_id), so.thecase 
from (
    select 
    *, 
    case 
     when subtotal_amount < 99.99 then 'under 100' 
     when subtotal_amount between 100.00 and 149.99 then '100-149' 
     when subtotal_amount between 150.00 and 249.99 then '150-249' 
     when subtotal_amount between 250.00 and 399.99 then '250-399' 
     when subtotal_amount between 400.00 and 499.99 then '400-499' 
     when subtotal_amount > 500 then '500+' 
    end AS thecase 
    from shop_order 
) so 
where 
    so.created_at between '2015-11-29 23:59:59' and '2015-11-31 00:00:01' 
    and so.thecase is not null 
group by 
    so.thecase 
+0

这很有趣,在这个例子中运行良好,因为我正在处理少量记录,但是这对于大量数据是否值得呢?子查询减慢了一些事情的正确性? – Bartonb12