在 Mysql 中使用 First_Value 函数时值错误
Wrong value when using First_Value function in Mysql
我需要根据这个table准备一份报告,我只能阅读:
想法是根据更高的 activity 识别为每个观察结果获取最后一个值。例如,观察 10 的值对应于 activity 数字 19。
到目前为止,这是我的代码:
select
first_value(text) over (partition by employee order by case when observation = 10 then activity else 0 end desc) as "Obs 10",
first_value(number) over (partition by employee order by case when observation = 20 then activity else 0 end desc) as "Obs 20",
first_value(dropdown) over (partition by employee order by case when observation = 40 then activity else 0 end desc) as "Obs 40"
-- the same for the rest of the observations
from employee_proc
但是,该员工可能与其他在执行查询时尚未注册的观察相关联。
如果我为这个员工包含这段代码:
...
first_value(text) over (partition by employee order by case when observation = 120 then activity else 0 end desc) as "Obs 120",
...
我得到了一个错误的值而不是 null(假设尚未为他注册观察)。
如何避免得到这种结果?。是否有另一种方法来获得最终结果,另一种更优化的方法?
此致。
您在问题中显示的结果可以通过以下查询更有效地实现:
create temporary table max_activity
select observation,max(activity) from employee_proc group by 1;
select employee,
activity,
MAX(IF(observation = 10, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs10,
MAX(IF(observation = 20, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs20,
MAX(IF(observation = 30, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs30,
MAX(IF(observation = 40, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs40,
MAX(IF(observation = 50, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs50,
MAX(IF(observation = 60, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs60,
MAX(IF(observation = 70, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs70,
MAX(IF(observation = 80, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs80,
MAX(IF(observation = 90, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs90,
MAX(IF(observation = 100, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs100,
MAX(IF(observation = 110, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs110
from employee_proc
inner join max_activity
on employee_proc.activity = max_activity.activity
group by 1,2;
我需要根据这个table准备一份报告,我只能阅读:
想法是根据更高的 activity 识别为每个观察结果获取最后一个值。例如,观察 10 的值对应于 activity 数字 19。
到目前为止,这是我的代码:
select
first_value(text) over (partition by employee order by case when observation = 10 then activity else 0 end desc) as "Obs 10",
first_value(number) over (partition by employee order by case when observation = 20 then activity else 0 end desc) as "Obs 20",
first_value(dropdown) over (partition by employee order by case when observation = 40 then activity else 0 end desc) as "Obs 40"
-- the same for the rest of the observations
from employee_proc
但是,该员工可能与其他在执行查询时尚未注册的观察相关联。
如果我为这个员工包含这段代码:
...
first_value(text) over (partition by employee order by case when observation = 120 then activity else 0 end desc) as "Obs 120",
...
我得到了一个错误的值而不是 null(假设尚未为他注册观察)。
如何避免得到这种结果?。是否有另一种方法来获得最终结果,另一种更优化的方法?
此致。
您在问题中显示的结果可以通过以下查询更有效地实现:
create temporary table max_activity
select observation,max(activity) from employee_proc group by 1;
select employee,
activity,
MAX(IF(observation = 10, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs10,
MAX(IF(observation = 20, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs20,
MAX(IF(observation = 30, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs30,
MAX(IF(observation = 40, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs40,
MAX(IF(observation = 50, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs50,
MAX(IF(observation = 60, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs60,
MAX(IF(observation = 70, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs70,
MAX(IF(observation = 80, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs80,
MAX(IF(observation = 90, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs90,
MAX(IF(observation = 100, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs100,
MAX(IF(observation = 110, ifnull(TEXT_,ifnull(date_in,ifnull(number,dropdown))),NULL)) AS Obs110
from employee_proc
inner join max_activity
on employee_proc.activity = max_activity.activity
group by 1,2;