在 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
我写了一个查询,其中 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