他们的 SQL 函数是否可以使用下面的查询同时提供负值和正值?

Is their an SQL function that can give me both a negative & positive value using the query below?

我试图做的是通过计算当前月份的所有新用户减去上个月的新用户,然后将增加量除以上个月的数量,然后乘以 100 来显示一个值。这将得到增加的百分比但从不显示负数,我意识到使用 abs() 将负数转换为正数,它们是允许我这样做的函数吗?

谢谢。

select round(abs
((select count(id) from users where 
month(created_at) = month(current_date())
and
YEAR(created_at) = year(current_date()))
-
(select count(id) from users where 
month(created_at) = month(current_date - interval 1 MONTH)
and
YEAR(created_at) = year(current_date - interval 1 MONTH)))
/
(select count(id) from users where 
month(created_at) = month(current_date())
and
YEAR(created_at) = year(current_date()))
*100, 0)
as abs_diff
from users
limit 1
;

我在想这样的事情:

select ym.*,
       (this_month - last_month) * 100.0 / last_month
from (select year(created_at) as yyyy, month(created_at) as mm, count(*) as this_month,
             lag(count(*)) over (order by min(created_at)) as prev_month
      from users
      group by yyyy, mm
     ) ym;

Window 函数是进行逐月比较的更简单的方法。

如果您只想要当月的这个,您可以添加:

order by yyyy desc, mm desc
limit 1

获取当月新增用户数:

count(case when last_day(created_at) = last_day(current_date) then 1 end)

以及上月新增用户数:

count(case when last_day(created_at) = last_day(current_date - interval 1 month) then 1 end)

所以在乘以 100 之前将这些数字相除并减去 1:

select
  100 * (
    count(case when last_day(created_at) = last_day(current_date) then 1 end) / 
    nullif(count(case when last_day(created_at) = last_day(current_date - interval 1 month) then 1 end), 0) 
    - 1
  ) abs_diff
from users
where date(created_at) > last_day(current_date - interval 2 month)

函数nullif()会returnnull如果上个月的新用户数是0以避免被0除.

查看简化版 demo.