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

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

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

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

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

Я думаю, что это происходит из раздела вокруг строки 89 (отмеченной **), но я не могу понять, каким должен быть синтаксис — я пытался скопировать разделы WITH/AS из docs, но либо я все еще делаю ошибку, либо ошибка где-то еще. Вероятно, ниже много повторяющегося/лишнего кода, но я подумал, что лучше включить его весь, так как я легко мог внести другие ошибки, когда перешел на синтаксис 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

person thumbtackthief    schedule 12.09.2014    source источник
comment
показать вывод \d timeloggedtoday   -  person Alex Dvoretsky    schedule 12.09.2014
comment
Какой мерзкий запрос. Я уверен, что это можно сделать намного приятнее, чем это. Сайт sqlfiddle.com с некоторыми примерами данных был бы очень полезен.   -  person Craig Ringer    schedule 12.09.2014
comment
Да я и не писал. Это страшно. Тем не менее, это очень повторяется, так что это не так плохо, как кажется. @AlexDvoretsky, извини, но я очень новичок во всем этом и не понимаю, о чем ты просишь.   -  person thumbtackthief    schedule 12.09.2014
comment
@thumbtackthief Он просит вас подключиться к клиенту командной строки psql и запустить \d timeloggedtoday, чтобы показать определение таблицы. Так как нет такой таблицы, которая не будет работать, конечно; вам понадобятся \d worklog и \d app_user, чтобы показать базовые таблицы.   -  person Craig Ringer    schedule 13.09.2014
comment
клиент командной строки у меня не работает. Я буду продолжать пытаться заставить его работать.   -  person thumbtackthief    schedule 15.09.2014
comment
Я использую pgadmin3, если я могу что-то там сделать, я предоставлю вам соответствующую информацию.   -  person thumbtackthief    schedule 15.09.2014


Ответы (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",

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

person user17130    schedule 13.09.2014
comment
Вполне возможно, что я неправильно это понимаю, но я думал, что проблема в том, что псевдоним timeloggedToday создавался неправильно. (timelogged1daysago также вызовет ту же ошибку, как и другие подобные псевдонимы, но сначала он попадет в timeloggedToday, и я почти уверен, что они будут одной и той же синтаксической причиной ошибки) - person thumbtackthief; 15.09.2014
comment
Да, ты прав. когда я посмотрел на него, я сначала подумал, что вы спорите с тем, что было показано. - person user17130; 16.09.2014
comment
Эй, это работает! Ну, я все равно получил новое сообщение об ошибке. Жалоба на Ifnull в строке 8. Я даю вам награду - большое спасибо! - person thumbtackthief; 16.09.2014
comment
поищите объединение() в документе - person user17130; 16.09.2014