【问题标题】:Is there a way to display negative values with the case function?有没有办法用 case 函数显示负值?
【发布时间】:2020-06-14 07:02:15
【问题描述】:

问题:

提供一份报告,显示客户的全名(名字和姓氏一起)、山寨名称、山寨的地区名称、预订日期(格式为 2017 年 12 月 15 日)、预订价格、以及该小屋的预订价格与所有小屋的平均预订价格之间的差额(以 $yy.y 格式,例如 $25.6 格式,截断到最接近的小数点后 1 位),按全名降序排列。

我的回答:

SELECT CONCAT(Customer_FName," ",Customer_LName) AS 'Name', Cottage_Name, Region_Name, 
DATE_FORMAT(Booking_Date,"%D %M %Y" ) AS 'Date Booked', Booking_Price,
CASE 
    WHEN AVG(Booking_Price) < Booking_Price THEN Booking_Price - AVG(Booking_Price)
    ELSE -1 * (AVG(Booking_Price) - Booking_Price)
END AS 'Diff From Average'

FROM Customer

JOIN Booking USING(Customer_ID)
JOIN Cottage
JOIN Region
GROUP BY Name;

我的输出:

所需的输出必须显示负值而不是 0

我的问题:有谁知道可以与CASE... WHEN 执行相同操作并显示负值的函数?

SQLFiddle(包含数据和所有必要的文件):http://sqlfiddle.com/#!9/8a40db/2/0

ERD:

问题提示:

【问题讨论】:

    标签: mysql date join average window-functions


    【解决方案1】:

    只有零,因为平均值与预订价格相同

    但是根本不需要你的理由

    您最好使用正确的连接和 ON clqause

    SELECT 
        CONCAT(Customer_FName," ",Customer_LName) AS 'Name'
        , Cottage_Name
         , Region_Name, 
         DATE_FORMAT(Booking_Date,"%D %M %Y" ) AS 'Date Booked'
        , Booking_Price
        ,
        CONCAT('$',ROUND((Booking_Price - AVG(Booking_Price)),1)) AS 'Diff From Average'
    FROM Customer
        JOIN Booking USING(Customer_ID)
        JOIN Cottage
       JOIN Region
    GROUP BY Name;
    
    
    
    Name            Cottage_Name                        Region_Name     Date Booked         Booking_Price   Diff From Average
    Bob Perkins     Atlantic Beach Resort Cottage 1     Halifax         10th January 2018   144             $0.0
    Charlie Oscar   Atlantic Beach Resort Cottage 1     Halifax         15th January 2018   1176            $294.0
    Eve Evenfield   Atlantic Beach Resort Cottage 1     Halifax         22nd December 2017  654             $0.0
    Frank Mitchell  Atlantic Beach Resort Cottage 1     Halifax         15th January 2018   384             $0.0
    Grace Damon     Atlantic Beach Resort Cottage 1     Halifax         1st January 2018    170             $0.0
    Student DalFCS  Atlantic Beach Resort Cottage 1     Halifax         15th January 2018   584             $154.5
    

    【讨论】:

    • 问题是“所有别墅的平均预订价格”我有点困惑,因为问题暗示我将发布为 edit1
    • 我解决问题的技巧是编写一些适用于某些列的内容,然后一点一点地实现一些代码。
    • 我改变了它适合这个问题。我删除了平均值,因为我添加了它来证明答案。现在 ot 显示美元符号并将结果四舍五入到 1 位。
    【解决方案2】:

    您的查询未正确聚合g,尽管 MySQL 对它的编译不够宽松。

    如果您运行的是 MySQL 8.0,您可以使用窗口函数来实现:

    select
        concat(c.Customer_FName, ' ', c.Customer_LName) AS Name, 
        b.Cottage_Name, 
        r.Region_Name, 
        DATE_FORMAT(Booking_Date,"%D %M %Y" ) AS Date_Booked, 
        b.Booking_Price,
        AVG(b.Booking_Price) OVER() - Booking_Price diff_from_average
    from customer c
    inner join booking b using(customer_id)
    inner join region r using(??)
    

    在早期版本中,您可以使用聚合查询来计算总体平均值:

    select
        concat(c.Customer_FName, ' ', c.Customer_LName) AS Name, 
        b.Cottage_Name, 
        r.Region_Name, 
        date_format(Booking_Date,"%D %M %Y" ) AS Date_Booked, 
        b.Booking_Price,
        a.avg_booking_Price - Booking_Price diff_from_average
    from customer c
    inner join booking b using(customer_id)
    inner join region r using(??)
    cross join (select avg(booking_price) avg_booking_price from booking) a
    

    旁注:

    • 我添加了表别名并尝试在列前加上相关表 - 您可能需要查看

    • 您在region 上缺少连接条件

    【讨论】:

    • 这种问题需要别名吗?为什么 Region 上的 join 需要条件?
    • 只要查询中涉及多个表,别名就很有用 - 为列添加前缀可以明确它们来自哪个表(并避免名称冲突)。至于region:你需要一个反映bookingregion之间关系的连接条件,否则你会得到两个表行的笛卡尔积。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2013-08-29
    • 2021-05-22
    • 2021-01-15
    • 2015-07-30
    相关资源
    最近更新 更多