在 postgresql 中以特定模式显示列

showing columns in a particular pattern in postgresql

我写了一个查询,其中 returns table 显示公司每个人每月的总工作时间。所以结果是:

name*****jan************feb**********march ......... dec
Tom     170:24:31    186:27:09    140:00:00........158:17:56     

我需要一个提供以下输出的查询:

name***jan***jan_salary****feb***feb_salary***....***dec***dec_salary      

每个月的工资是当月的总工作时间乘以150$。我怎样才能做到这一点? 下面是我为计算每个人每个月的总工作时间而编写的查询:

with hours as (
  select "Staff_Id", 
     "Date", 
     case 
       when row_number() over w % 2 = 0 then 
          TO_CHAR("Time" - lag("Time") over w,'HH24:MI:SS')
     end as hours
  from "Org"."Clock"
  window w as (partition by "Staff_Id", "Date" order by "Time")
), hours_per_month as (
  select "Staff_Id", 
     extract(year from "Date")::int as work_year,
     extract(month from "Date")::int as work_month,
     sum(hours::interval) work_hours
  from hours
  where hours is not null
  group by "Staff_Id", work_year, work_month
)
select "Staff_Id", 
   work_year,
   sum("work_hours") filter (where work_month = 1) as jan,
   sum("work_hours") filter (where work_month = 2) as feb,
   sum("work_hours") filter (where work_month = 3) as march,
   sum("work_hours") filter (where work_month = 4) as april,
   sum("work_hours") filter (where work_month = 5) as may,
   sum("work_hours") filter (where work_month = 6) as june,
   sum("work_hours") filter (where work_month = 7) as july,
   sum("work_hours") filter (where work_month = 8) as aug,
   sum("work_hours") filter (where work_month = 9) as sep,
   sum("work_hours") filter (where work_month = 10) as oct,
   sum("work_hours") filter (where work_month = 11) as nov,
   sum("work_hours") filter (where work_month = 12) as dec
from hours_per_month  
group by "Staff_Id", work_year

我认为您可以将工资添加到 "hours_per_month" 子查询中,如下所示:

select "Staff_Id", 
   extract(year from "Date")::int as work_year,
   extract(month from "Date")::int as work_month,
   sum(hours::interval) work_hours,
   trunc (extract (epoch from sum(hours::interval)) / 3600) * 150 as salary
from hours
where hours is not null
group by "Staff_Id", work_year, work_month

这假定您要支付整个小时的费用(15.8 小时 = 15 小时的工资),但如果不是,那很容易调整。

extract (hours 也可能有效,但如果总小时数 > 24 则无效。在我看来,假设它会起作用是不值得的,即使在这种不现实的情况下也是如此假设一个人一次工作超过 24 小时。此外,您以后可能会无意中克隆此代码以用于 "machine hours," 之类的东西,在这种情况下,这是很有可能的。

然后,在您的主查询中:

select "Staff_Id", 
   work_year,
   sum("work_hours") filter (where work_month = 1) as jan,
   sum(salary) filter (where work_month = 1) as jan_salary,
   sum("work_hours") filter (where work_month = 2) as feb,
   sum(salary) filter (where work_month = 2) as feb_salary,
   ...
   sum("work_hours") filter (where work_month = 12) as dec,
   sum(salary) filter (where work_month = 12) as dec_salary
from hours_per_month  
group by "Staff_Id", work_year

完全跑题了,我并不是要告诉你如何过你的生活,但是当我看到字段和 table 名称周围的引号时,除非它在查询的最后一步(渲染输出)它让我毛骨悚然。它还引入了很多错误的机会。碰巧,我并不孤单:

https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_upper_case_table_or_column_names