Столбец Postgres не существует

Кто-то еще написал запрос SQL Server, который сработал, и у меня есть задача перенести его на Postgres.

Я на самом деле не знаю ни одной базы данных, кроме самых простых команд SQL (я прорабатываю учебник и буду продолжать в любом случае, но я бы хотел решить эту проблему раньше, чем позже).

Во всяком случае, я получаю ошибку, что в строке 4,

ОШИБКА: столбец timeloggedtoday.date_logged не существует

Я думаю, что это происходит из раздела вокруг строки 89 (помеченного **), но я не могу понять, каким должен быть синтаксис - я пытался скопировать разделы WITH/AS из документов, но либо все еще совершаете ошибку или ошибка где-то еще. Вероятно, ниже приведено много повторяющихся / посторонних кодов, но я подумал, что лучше включить их все, так как я легко мог внести другие ошибки при переходе на синтаксис Postgres.

РЕДАКТИРОВАТЬ:

Если я удалю оскорбительные разделы, ошибка изменится на

ОШИБКА: столбец timelogged1daysago.date_logged не существует

который является следующей партией подобного кода, что наводит меня на мысль, что я делаю некоторую синтаксическую ошибку при именовании моей временной таблицы (правильная терминология?), но я не вижу, что не так, и трудно найти соответствующий раздел в документации Гуглить "с" или "как", что неудивительно, бесполезно.

SELECT users.author,
       users.display_name,
       timeloggedToday.date_logged "DATE_LOGGED_TODAY",
       timeloggedToday.time_in_hours "TIME_IN_HOURS_TODAY",
       timeloggedToday.difference_days "DIFFERENCE_DAYS_TODAY",
       CASE
           WHEN Ifnull(timeloggedToday.time_in_hours, 0) = 0 THEN 'No Time Logged'
           WHEN timeloggedToday.time_in_hours < 3.0 THEN 'User has not logged sufficient time'
           ELSE 'user has logged sufficient time'
       END "STATUS_TODAY",
       timelogged1daysago.date_logged "DATE_LOGGED_1DAYSAGO",
       timelogged1daysago.time_in_hours "TIME_IN_HOURS_1DAYSAGO",
       timelogged1daysago.difference_days "DIFFERENCE_DAYS_1DAYSAGO",
       CASE
           WHEN Ifnull(timelogged1daysago.time_in_hours, 0) = 0 THEN 'No Time Logged'
           WHEN timelogged1daysago.time_in_hours < 3.0 THEN 'User has not logged sufficient time'
           ELSE 'user has logged sufficient time'
       END "STATUS_1DAYSAGO",
       timelogged2daysago.date_logged "DATE_LOGGED_2DAYSAGO",
       timelogged2daysago.time_in_hours "TIME_IN_HOURS_2DAYSAGO",
       timelogged2daysago.difference_days "DIFFERENCE_DAYS_2DAYSAGO",
       CASE
           WHEN Ifnull(timelogged2daysago.time_in_hours, 0) = 0 THEN 'No Time Logged'
           WHEN timelogged2daysago.time_in_hours < 3.0 THEN 'User has not logged sufficient time'
           ELSE 'user has logged sufficient time'
       END "STATUS_2DAYSAGO",
       timelogged3daysago.date_logged "DATE_LOGGED_3DAYSAGO",
       timelogged3daysago.time_in_hours "TIME_IN_HOURS_3DAYSAGO",
       timelogged3daysago.difference_days "DIFFERENCE_DAYS_3DAYSAGO",
       CASE
           WHEN Ifnull(timelogged3daysago.time_in_hours, 0) = 0 THEN 'No Time Logged'
           WHEN timelogged3daysago.time_in_hours < 3.0 THEN 'User has not logged sufficient time'
           ELSE 'user has logged sufficient time'
       END "STATUS_3DAYSAGO",
       timelogged4daysago.date_logged "DATE_LOGGED_4DAYSAGO",
       timelogged4daysago.time_in_hours "TIME_IN_HOURS_4DAYSAGO",
       timelogged4daysago.difference_days "DIFFERENCE_DAYS_4DAYSAGO",
       CASE
           WHEN Ifnull(timelogged4daysago.time_in_hours, 0) = 0 THEN 'No Time Logged'
           WHEN timelogged4daysago.time_in_hours < 3.0 THEN 'User has not logged sufficient time'
           ELSE 'user has logged sufficient time'
       END "STATUS_4DAYSAGO",
       timelogged5daysago.date_logged "DATE_LOGGED_5DAYSAGO",
       timelogged5daysago.time_in_hours "TIME_IN_HOURS_5DAYSAGO",
       timelogged5daysago.difference_days "DIFFERENCE_DAYS_5DAYSAGO",
       CASE
           WHEN Ifnull(timelogged5daysago.time_in_hours, 0) = 0 THEN 'No Time Logged'
           WHEN timelogged5daysago.time_in_hours < 3.0 THEN 'User has not logged sufficient time'
           ELSE 'user has logged sufficient time'
       END "STATUS_5DAYSAGO",
       timelogged6daysago.date_logged "DATE_LOGGED_6DAYSAGO",
       timelogged6daysago.time_in_hours "TIME_IN_HOURS_6DAYSAGO",
       timelogged6daysago.difference_days "DIFFERENCE_DAYS_6DAYSAGO",
       CASE
           WHEN Ifnull(timelogged6daysago.time_in_hours, 0) = 0 THEN 'No Time Logged'
           WHEN timelogged6daysago.time_in_hours < 3.0 THEN 'User has not logged sufficient time'
           ELSE 'user has logged sufficient time'
       END "STATUS_6DAYSAGO",
       timelogged7daysago.date_logged "DATE_LOGGED_7DAYSAGO",
       timelogged7daysago.time_in_hours "TIME_IN_HOURS_7DAYSAGO",
       timelogged7daysago.difference_days "DIFFERENCE_DAYS_7DAYSAGO",
       CASE
           WHEN Ifnull(timelogged7daysago.time_in_hours, 0) = 0 THEN 'No Time Logged'
           WHEN timelogged7daysago.time_in_hours < 3.0 THEN 'User has not logged sufficient time'
           ELSE 'user has logged sufficient time'
       END "STATUS_7DAYSAGO",
       lastReportedTime.last_time_logged
FROM
  (SELECT lower_child_name AS "author",
          cwd_user.display_name
   FROM cwd_membership
   LEFT JOIN cwd_user ON (cwd_membership.lower_child_name = cwd_user.user_name
                          AND cwd_user.directory_id = cwd_membership.directory_id)
   WHERE lower_parent_name = 'jira-developers'
     AND cwd_membership.directory_id = 10100) users
**LEFT JOIN
  (SELECT app_user.lower_user_name,
          to_char(startdate, '%Y-%m-%d') AS "DATE_LOGGED",
          Sum(timeworked) / 3600 "TIME_IN_HOURS",
          startdate - Now() "DIFFERENCE_DAYS"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   WHERE to_char(Now() - INTERVAL '8 days', '%Y-%m-%d') < to_char(startdate, '%Y-%m-%d')
     AND startdate - Now() = INTERVAL '0 days'
   GROUP BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now()),
            worklog.startdate
   ORDER BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now())) timeloggedToday ON timeloggedToday.lower_user_name = users.author**
LEFT JOIN
  (SELECT app_user.lower_user_name,
          to_char(startdate, '%Y-%m-%d') AS "DATE_LOGGED",
          Sum(timeworked) / 3600 "TIME_IN_HOURS",
          startdate - Now() "DIFFERENCE_DAYS"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   WHERE to_char(Now() - INTERVAL '8 days', '%Y-%m-%d') < to_char(startdate, '%Y-%m-%d')
     AND startdate - Now() = INTERVAL '-1 days'
   GROUP BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now()),
            worklog.startdate
   ORDER BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now())) timelogged1daysago ON timelogged1daysago.lower_user_name = users.author
LEFT JOIN
  (SELECT app_user.lower_user_name,
          to_char(startdate, '%Y-%m-%d') AS "DATE_LOGGED",
          Sum(timeworked) / 3600 "TIME_IN_HOURS",
          startdate - Now() "DIFFERENCE_DAYS"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   WHERE to_char(Now() - INTERVAL '8 days', '%Y-%m-%d') < to_char(startdate, '%Y-%m-%d')
     AND startdate - Now() = INTERVAL '-2 days'
   GROUP BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now()),
            worklog.startdate
   ORDER BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now())) timelogged2daysago ON timelogged2daysago.lower_user_name = users.author
LEFT JOIN
  (SELECT app_user.lower_user_name,
          to_char(startdate, '%Y-%m-%d') AS "DATE_LOGGED",
          Sum(timeworked) / 3600 "TIME_IN_HOURS",
          startdate - Now() "DIFFERENCE_DAYS"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   WHERE to_char(Now() - INTERVAL '8 days', '%Y-%m-%d') < to_char(startdate, '%Y-%m-%d')
     AND startdate - Now() = INTERVAL '-3 days'
   GROUP BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now()),
            worklog.startdate
   ORDER BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now())) timelogged3daysago ON timelogged3daysago.lower_user_name = users.author
LEFT JOIN
  (SELECT app_user.lower_user_name,
          to_char(startdate, '%Y-%m-%d') AS "DATE_LOGGED",
          Sum(timeworked) / 3600 "TIME_IN_HOURS",
          startdate - Now() "DIFFERENCE_DAYS"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   WHERE to_char(Now() - INTERVAL '8 days', '%Y-%m-%d') < to_char(startdate, '%Y-%m-%d')
     AND startdate - Now() = INTERVAL '-4 days'
   GROUP BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now()),
            worklog.startdate
   ORDER BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now())) timelogged4daysago ON timelogged4daysago.lower_user_name = users.author
LEFT JOIN
  (SELECT app_user.lower_user_name,
          to_char(startdate, '%Y-%m-%d') AS "DATE_LOGGED",
          Sum(timeworked) / 3600 "TIME_IN_HOURS",
          startdate - Now() "DIFFERENCE_DAYS"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   WHERE to_char(Now() - INTERVAL '8 days', '%Y-%m-%d') < to_char(startdate, '%Y-%m-%d')
     AND startdate - Now() = INTERVAL '-5 days'
   GROUP BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now()),
            worklog.startdate
   ORDER BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now())) timelogged5daysago ON timelogged5daysago.lower_user_name = users.author
LEFT JOIN
  (SELECT app_user.lower_user_name,
          to_char(startdate, '%Y-%m-%d') AS "DATE_LOGGED",
          Sum(timeworked) / 3600 "TIME_IN_HOURS",
          startdate - Now() "DIFFERENCE_DAYS"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   WHERE to_char(Now() - INTERVAL '8 days', '%Y-%m-%d') < to_char(startdate, '%Y-%m-%d')
     AND startdate - Now() = INTERVAL '-6 days'
   GROUP BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now()),
            worklog.startdate
   ORDER BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now())) timelogged6daysago ON timelogged6daysago.lower_user_name = users.author
LEFT JOIN
  (SELECT app_user.lower_user_name,
          to_char(startdate, '%Y-%m-%d') AS "DATE_LOGGED",
          Sum(timeworked) / 3600 "TIME_IN_HOURS",
          startdate - Now() "DIFFERENCE_DAYS"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   WHERE to_char(Now() - INTERVAL '8 days', '%Y-%m-%d') < to_char(startdate, '%Y-%m-%d')
     AND startdate - Now() = INTERVAL '-7 days'
   GROUP BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now()),
            worklog.startdate
   ORDER BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now())) timelogged7daysago ON timelogged7daysago.lower_user_name = users.author
LEFT JOIN
  (SELECT app_user.lower_user_name,
          Max(startdate) AS "last_time_logged"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   GROUP BY app_user.lower_user_name) lastReportedTime ON lastReportedTime.lower_user_name = users.author

РЕДАКТИРОВАТЬ: более простой запрос

Я думаю, что я отредактировал некоторые посторонние вещи в надежде найти эту ошибку. В любом случае, этот более короткий запрос выдает мне ту же ошибку, по крайней мере, так что, возможно, немного легче помочь мне в отладке:

SELECT users.author,
       users.display_name,
       timeloggedToday.date_logged "DATE_LOGGED_TODAY",
       timeloggedToday.time_in_hours "TIME_IN_HOURS_TODAY",
       timeloggedToday.difference_days "DIFFERENCE_DAYS_TODAY",
       CASE
           WHEN Ifnull(timeloggedToday.time_in_hours, 0) = 0 THEN 'No Time Logged'
           WHEN timeloggedToday.time_in_hours < 3.0 THEN 'User has not logged sufficient time'
           ELSE 'user has logged sufficient time'
       END "STATUS_TODAY",
       lastReportedTime.last_time_logged
FROM
  (SELECT lower_child_name AS "author",
          cwd_user.display_name
   FROM cwd_membership
   LEFT JOIN cwd_user ON (cwd_membership.lower_child_name = cwd_user.user_name
                          AND cwd_user.directory_id = cwd_membership.directory_id)
   WHERE lower_parent_name = 'jira-developers'
     AND cwd_membership.directory_id = 10100) users
LEFT JOIN
  (SELECT app_user.lower_user_name,
          to_char(startdate, '%Y-%m-%d') AS "DATE_LOGGED",
          Sum(timeworked) / 3600 "TIME_IN_HOURS",
          startdate - Now() "DIFFERENCE_DAYS"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   WHERE to_char(Now() - INTERVAL '8 days', '%Y-%m-%d') < to_char(startdate, '%Y-%m-%d')
     AND startdate - Now() = INTERVAL '0 days'
   GROUP BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now()),
            worklog.startdate
   ORDER BY app_user.lower_user_name,
            to_char(startdate, '%Y-%m-%d'),
            Date(Now())) timeloggedToday ON timeloggedToday.lower_user_name = users.author

LEFT JOIN
  (SELECT app_user.lower_user_name,
          Max(startdate) AS "last_time_logged"
   FROM worklog
   LEFT JOIN app_user ON worklog.author = app_user.user_key
   GROUP BY app_user.lower_user_name) lastReportedTime ON lastReportedTime.lower_user_name = users.author

1 ответ

Решение

Отредактировано: цитируемая заглавная буква соответствует запросу. В выводе второго сбоя ниже видно, что Postgres не нравится верхний регистр. У него есть привычка нижнего регистра всего, если вы не заставляете " цитаты.

--fails
select a
from
(select 1 as "A") as t;

--fails
select A
from
(select 1 as "A") as t;

--works
select "A"
from
(select 1 as "A") as t;

psql:new.sql:5: ERROR:  column "a" does not exist
LINE 1: select a
               ^
psql:new.sql:10: ERROR:  column "a" does not exist
LINE 1: select A
               ^
 A 
───
 1
(1 row)


select ...
timeloggedToday.date_logged "DATE_LOGGED_TODAY",
-- should be: timeloggedToday."DATE_LOGGED" "DATE_LOGGED_TODAY",

...

LEFT JOIN
  (SELECT app_user.lower_user_name,
          to_char(startdate, '%Y-%m-%d') AS "DATE_LOGGED",
          Sum(timeworked) / 3600 "TIME_IN_HOURS",
          startdate - Now() "DIFFERENCE_DAYS"
   ...
  ) timeloggedToday ON timeloggedToday.lower_user_name = users.author;

Я бы подумал об избавлении от заглавных букв и кавычек. Это просто вызовет головные боли. В качестве примечания вы можете написать левое соединение только один раз:

-- instead of enumerating each possible interval  
WHERE to_char(Now() - INTERVAL '8 days', '%Y-%m-%d') < to_char(startdate, '%Y-%m-%d')
-- select the interval
now()::date - start_date as diff
-- then build up your columns like:
case(case when diff=0 then date_logged else null end) as date_logged_today
case(case when diff=1 then date_logged else null end) as date_logged_yesterday
-- and so on ...

Также вы могли бы сделать

CASE
   WHEN Ifnull(timeloggedToday.time_in_hours, 0) = 0 THEN 'No Time Logged'
   WHEN timeloggedToday.time_in_hours < 3.0 THEN 'User has not logged sufficient time' 
   ELSE 'user has logged sufficient time'
 END "STATUS_TODAY",

в функцию, чтобы избавиться от утомительной избыточности.

Другие вопросы по тегам