草庐IT

值范围的 MySQL CASE 不起作用,但嵌套的 IF 可以吗?

coder 2023-10-10 原文

我可能遗漏了一些非常非常简单的东西,但我终其一生都无法弄清楚我做错了什么......

我有一个查询,用于提取人们在志愿服务中完成的小时数,然后根据提交的小时数为他们分配奖励。不难...

嵌套的 IF 解决方案很糟糕,只是一个后备方案,看看它是否只是 CASE 搞砸了。事实证明,janky 嵌套 IF 解决方案完美运行,而我的 CASE 解决方案仍然存在问题。

该查询每年只运行一次以获取最终结果,因此性能并不是真正的问题(嵌套 IF 查询当前的执行时间为 0.0095 秒/700 行,这已经足够了),它更多的是事实上,它无法正常工作让我非常恼火,我想了解原因以供将来引用。

作为引用,小时值存储为 DECIMAL(8,2) , 随后 total_hours 的值也是相同类型。

我正在寻找的输出是:

| id | first_name | last_name  | total_hours | award    |
|----|------------|------------|-------------|----------|
| 1  | Bob        | Harrington | 0.50        | Silver   |
| 2  | Jim        | Halpert    | 800.00      | Platinum |
| 3  | Dwight     | Shrute     | 130.00      | Gold     |
| 4  | Michael    | Scott      | 5.00        | Bronze   |

CASE 语句导致 award 的所有行的值都为“小于 1 小时” , 除了 total_hours 等于 1.00 的那些,其中 award 的值等于“青铜”。

按照上面的示例,嵌套的 IF 语句导致正确生成表。

这是我当前的 CASE 查询,它不起作用:

SELECT
    m.id,
    m.first_name,
    m.last_name,
    total_hours,
    CASE total_hours
        WHEN total_hours >= 1 <= 50 THEN
            'Bronze'
        WHEN total_hours >= 51 <= 125 THEN
            'Silver'
        WHEN total_hours >= 126 <= 249 THEN
            'Gold'
        WHEN total_hours >= 250 THEN
            'Platinum'
        ELSE
            'Less than 1 hour'
    END AS award
FROM (
    SELECT member_id, sum(hours) total_hours
    FROM volunteering_hours
    WHERE authorise_date > 0 AND validate_date > 0 AND delete_date = 0
    GROUP BY member_id
) hour_query
LEFT JOIN members m ON m.id = member_id
ORDER BY total_hours DESC

到目前为止我尝试了什么:

  • 将原始比较数值放在引号中。
  • 给比较数值保留小数位。
  • 只用一个比较来尝试 CASE 语句,就像测试一样; WHEN total_hours > 1 THEN 'GT 1' ELSE 'LT 1' END award , 所有仍以 LT 1 形式出现的列运行查询后 - 意味着它失败了。
  • 对 CASE 语句进行分组
  • 将每个范围比较的语法更改为 total_hours >= 1 && total_hours <= 50等等。它仍然产生了相同的失败结果

我当前的嵌套 IF 解决方案看起来很糟糕,但至少可以正常工作,是:

SELECT
    m.id,
    m.first_name,
    m.last_name,
    total_hours,
    IF(total_hours >= 1 && total_hours <= 50, 'Bronze',
        IF(total_hours >= 51 && total_hours <= 125, 'Silver',
            IF(total_hours >= 126 && total_hours <= 249, 'Gold',
                IF(total_hours >= 250, 'Platinum', 'Less than 1 hour')
            )
        )
    ) award
FROM (
    SELECT member_id, sum(hours) total_hours
    FROM volunteering_hours
    WHERE authorise_date > 0 AND validate_date > 0 AND delete_date = 0
    GROUP BY member_id
) hour_query
LEFT JOIN members m ON m.id = member_id
ORDER BY total_hours DESC

有人可以告诉我一些关于 CASE 为何不起作用的知识吗?

提前致谢。 :)

最佳答案

你很接近,但有一些语法错误。改为这样做:

CASE 
    WHEN total_hours >= 1 AND total_hours <= 50 THEN
        'Bronze'
    WHEN total_hours >= 51 AND total_hours <= 125 THEN
        'Silver'
    WHEN total_hours >= 126 AND total_hours <= 249 THEN
        'Gold'
    WHEN total_hours >= 250 THEN
        'Platinum'
    ELSE
        'Less than 1 hour'
END AS award

Sample simplified SQL Fiddle

关于值范围的 MySQL CASE 不起作用,但嵌套的 IF 可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29965729/

有关值范围的 MySQL CASE 不起作用,但嵌套的 IF 可以吗?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  3. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  4. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  5. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  6. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  7. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  8. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  9. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  10. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

随机推荐