sql选择数字分割聚合和函数

sql选择数字分割聚合和函数,sql,postgresql,Sql,Postgresql,我有这个模式 我想要一个查询来计算每个顾问每月每小时的成本。换言之,顾问每月有一份工资,我想将工资金额除以他/她当月工作的小时数 SELECT concat_ws(' ', consultants.first_name::text, consultants.last_name::text) as name, EXTRACT(MONTH FROM tasks.init_time) as task_month, SUM(tasks.finish_time::timestam

我有这个模式

我想要一个查询来计算每个顾问每月每小时的成本。换言之,顾问每月有一份工资,我想将工资金额除以他/她当月工作的小时数

SELECT
    concat_ws(' ', consultants.first_name::text, consultants.last_name::text) as name,
    EXTRACT(MONTH FROM tasks.init_time) as task_month,
    SUM(tasks.finish_time::timestamp::time - tasks.init_time::timestamp::time) as duration,
    EXTRACT(MONTH FROM salaries.payment_date) as salary_month,
    salaries.payment
FROM consultants
INNER JOIN tasks ON consultants.id = tasks.consultant_id
INNER JOIN salaries ON consultants.id = salaries.consultant_id
WHERE EXTRACT(MONTH FROM tasks.init_time) = EXTRACT(MONTH FROM salaries.payment_date)
GROUP BY (consultants.id, EXTRACT(MONTH FROM tasks.init_time), EXTRACT(MONTH FROM salaries.payment_date), salaries.payment);
在选择中不可能执行此操作

salaries.payment / SUM(tasks.finish_time::timestamp::time - tasks.init_time::timestamp::time)

还有别的办法吗?有可能在一个查询中解决它吗?

如果目标将它放在一个查询中,那么请确认,您是否尝试使用CTEs实现它? 像

;与cte_pymt
作为
(
//您现有的查询1
)
从cte_pymt中选择

如果目标是将其放在一个查询中,然后确认,您是否尝试使用CTEs实现它? 像

;与cte_pymt
作为
(
//您现有的查询1
)
从cte_pymt中选择
对此答案所作的假设: 我并不完全清楚该模型,因此我假设如下:

  • 您正在使用PostgreSQL
  • salaries.date
    被定义为一个
    date
    列,用于存储顾问获得报酬的日期
  • tasks.init_time
    task.finish_time
    定义为
    timestamp
    存储顾问开始和完成特定任务时的数据和时间

就我所知,你在上的加入仅这个月是错误的。首先,因为它还将包括不同年份的月份,但更重要的是,这将导致
工资
中的同一行多次出现。我认为您需要在完成日期加入:

FROM consultants c 
  JOIN tasks t ON c.id = t.consultant_id
  JOIN salaries s ON c.id = s.consultant_id 
                 AND t.init_time::date = s.payment_date --<< here
要获得每月每小时的成本,您需要将
时间间隔
(这是从一个时间戳中减去另一个时间戳的结果)转换为表示小时的十进制数,您可以通过从时间间隔中提取秒数,然后将其除以3600,例如

extract(epoch from sum(t.finish_time - t.init_time)) / 3600)
如果将付款总额除以该数字,则得到每月每小时的成本:

SELECT concat_ws(' ', c.first_name, c.last_name) as name,
       to_char(s.payment_date, 'yyyy-mm') as salary_month,
       extract(epoch from sum(t.finish_time - t.init_time)) / 3600 as worked_hours, 
       sum(s.payment) / (extract(epoch from sum(t.finish_time - t.init_time)) / 3600) as cost_per_hour
FROM consultants c 
  JOIN tasks t ON c.id = t.consultant_id
  JOIN salaries s ON c.id = s.consultant_id AND t.init_time::date = s.payment_date
GROUP BY c.id, to_char(s.payment_date, 'yyyy-mm') --<< no parentheses!
order by name, salary_month;
选择concat_ws(“”,c.名字,c.姓氏)作为名称,
将(s.付款日期,'yyyy-mm')作为每月工资,
提取(从总和(t.finish_time-t.init_time)中提取历元)/3600作为工作小时,
总(s.付款)/(从总(t.完成时间-t.初始时间)中提取历元)/3600,作为每小时的成本
顾问公司c
在c.id=t.consultant\u id上加入任务t
在c.id=s.consultant\u id和t.init\u time::date=s.payment\u date上加入工资s
按c.id分组,至字符(s.payment_date,'yyyy-mm')——对该答案的假设:
我并不完全清楚该模型,因此我假设如下:

  • 您正在使用PostgreSQL
  • salaries.date
    被定义为一个
    date
    列,用于存储顾问获得报酬的日期
  • tasks.init_time
    task.finish_time
    定义为
    timestamp
    存储顾问开始和完成特定任务时的数据和时间

就我所知,你在上的加入仅这个月是错误的。首先,因为它还将包括不同年份的月份,但更重要的是,这将导致
工资
中的同一行多次出现。我认为您需要在完成日期加入:

FROM consultants c 
  JOIN tasks t ON c.id = t.consultant_id
  JOIN salaries s ON c.id = s.consultant_id 
                 AND t.init_time::date = s.payment_date --<< here
要获得每月每小时的成本,您需要将
时间间隔
(这是从一个时间戳中减去另一个时间戳的结果)转换为表示小时的十进制数,您可以通过从时间间隔中提取秒数,然后将其除以3600,例如

extract(epoch from sum(t.finish_time - t.init_time)) / 3600)
如果将付款总额除以该数字,则得到每月每小时的成本:

SELECT concat_ws(' ', c.first_name, c.last_name) as name,
       to_char(s.payment_date, 'yyyy-mm') as salary_month,
       extract(epoch from sum(t.finish_time - t.init_time)) / 3600 as worked_hours, 
       sum(s.payment) / (extract(epoch from sum(t.finish_time - t.init_time)) / 3600) as cost_per_hour
FROM consultants c 
  JOIN tasks t ON c.id = t.consultant_id
  JOIN salaries s ON c.id = s.consultant_id AND t.init_time::date = s.payment_date
GROUP BY c.id, to_char(s.payment_date, 'yyyy-mm') --<< no parentheses!
order by name, salary_month;
选择concat_ws(“”,c.名字,c.姓氏)作为名称,
将(s.付款日期,'yyyy-mm')作为每月工资,
提取(从总和(t.finish_time-t.init_time)中提取历元)/3600作为工作小时,
总(s.付款)/(从总(t.完成时间-t.初始时间)中提取历元)/3600,作为每小时的成本
顾问公司c
在c.id=t.consultant\u id上加入任务t
在c.id=s.consultant\u id和t.init\u time::date=s.payment\u date上加入工资s

按c.id分组,到字符(s.payment_date,'yyyyy-mm')--根据
casts添加了
postgresql
标记,该标记的数据类型为
任务。完成时间
?重复的演员阵容似乎很奇怪。转换为
时间也意味着如果初始时间和完成时间之间的间隔超过一天(例如从21:00到07:00),则差异将不正确。当顾问获得报酬时,您是否每天都有一行?
salaries.date
具体包含哪些内容?根据
添加了
postgresql
标记::
castsWhat data type是
tasks.finish\u time
?重复的演员阵容似乎很奇怪。转换为
时间也意味着如果初始时间和完成时间之间的间隔超过一天(例如从21:00到07:00),则差异将不正确。当顾问获得报酬时,您是否每天都有一行?工资.日期的具体内容是什么?非常感谢你没有名字的马,回答得很好。这些假设是正确的。我没有意识到需要数据库,我认为这个查询可以用ansisql完成,但是类型date和timestamp不允许这样做。关于我在询问中的错误,你也是对的。谢谢你的sqlfiddle,Fiddle总是非常有用的。最后,也感谢您对括号的最后评论。唯一的问题是,这部分
和t.init\u time::date=s.payment\u date
是不必要的,并且破坏了查询。@agusgambina:The
和t.init\u time::date=s.payment\u date
条件只使用
init\u time
部分,并假设
payment\u date
日期。如果不将
init\u time
强制转换为dat