使用列别名在PostgreSQL中进行操作时出错

时间:2013-08-27 09:39:47

标签: sql postgresql

我遇到此查询的问题。我想为我的工资单系统进行操作。我这是我的查询不起作用。

查询:

select
    hrrawd_timein,
    hrrawd_shiftin,
    (
      (extract(hour from (hrrawd_timein::time))
      - extract(hour from (hrrawd_shiftin::time))
      )::numeric
    ) AS shiftinhours,
    (
      (extract(minute from (hrrawd_timein::time))
      - extract(minute from (hrrawd_shiftin::time))
      )::numeric
    ) AS shiftinminutes,
    (
      ((extract(hour from (hrrawd_timein::time))
      - extract(hour from (hrrawd_shiftin::time)
      ))*60)::numeric
    )
    + 
    (
      (extract(minute from (hrrawd_timein::time))
      - extract(minute from (hrrawd_shiftin::time))
      )::numeric
    ) AS Total,
    case
      when (Total >0) then 'Late' 
      else 'EARLY'
    end as remarks
  FROM hr.hrrawd;

错误:

> ERROR:  column "total" does not exist LINE 7: case when (Total >0)
> then 'Late'

3 个答案:

答案 0 :(得分:4)

我建议您在需要预先计算的列时使用common table expressions

with cte1 as (
    select
        hrrawd_timein, hrrawd_shiftin,
        (
           extract(hour from (hrrawd_timein::time)) -
           extract(hour from (hrrawd_shiftin::time))
        )::numeric as shiftinhours,
        (
           extract(minute from (hrrawd_timein::time)) -
           extract(minute from (hrrawd_shiftin::time))
        )::numeric as shiftinminutes
    from hr.hrrawd
), cte2 as (
    select
        *,
        shiftinhours * 60 + shiftinminutes as [total]
   from cte1
)
select
    *,
    case when [total] > 0 then 'Late' else 'Early' end as remarks
from cte2

我认为它比子查询更清晰。您也可以根据需要链接尽可能多的CTE,它可以帮助您保持DRY principle - 注意shiftinminutesshiftinhours仅计算一次而不是两次。可读性很重要,不做两次计算,将来很难维护。

顺便说一句,看看interval data type in PostgreSQL,你可以从中提取小时和分钟

答案 1 :(得分:1)

答案:

select
    *,
    case when (Total >0) then 'Late' 
     else 'EARLY' end as remarks
from (
    select  hrrawd_timein, hrrawd_shiftin,
    ((extract(hour from (hrrawd_timein::time)) - extract(hour from (hrrawd_shiftin::time)))::numeric) AS shiftinhours,
    ((extract(minute from (hrrawd_timein::time)) - extract(minute from (hrrawd_shiftin::time)))::numeric) AS shiftinminutes,
    (((extract(hour from (hrrawd_timein::time)) - extract(hour from (hrrawd_shiftin::time)))*60)::numeric)
     + 
     ((extract(minute from (hrrawd_timein::time)) - extract(minute from (hrrawd_shiftin::time)))::numeric) AS Total
    FROM hr.hrrawd) a;

答案 2 :(得分:1)

标准SQL不允许在任何其他位置使用列别名,而是使用ORDER BY。

您需要剪切和粘贴计算或更好地使用派生表:

SELECT
   hrrawd_timein, hrrawd_shiftin, 
   shiftinhours,
   shiftinminutes,
   Total,
   CASE WHEN (Total >0) THEN 'Late' ELSE 'EARLY' END AS remarks
FROM
 (
    SELECT  hrrawd_timein, hrrawd_shiftin, 
       ((EXTRACT(HOUR FROM (hrrawd_timein::TIME)) - EXTRACT(HOUR FROM (hrrawd_shiftin::TIME)))::NUMERIC) AS shiftinhours,
       ((EXTRACT(MINUTE FROM (hrrawd_timein::TIME)) - EXTRACT(MINUTE FROM (hrrawd_shiftin::TIME)))::NUMERIC) AS shiftinminutes,
       (((EXTRACT(HOUR FROM (hrrawd_timein::TIME)) - EXTRACT(HOUR FROM (hrrawd_shiftin::TIME)))*60)::NUMERIC)
        + ((EXTRACT(MINUTE FROM (hrrawd_timein::TIME)) - EXTRACT(MINUTE FROM (hrrawd_shiftin::TIME)))::NUMERIC) AS Total
    FROM hr.hrrawd
 ) AS dt