PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

невалидна препратка към запис в клауза FROM за таблица в заявка на Postgres

Обяснение за грешката

Непосредствената причина за съобщението за грешка е, че всяко изрично JOIN свързва по-силно от запетая (, ), което иначе е еквивалентно на CROSS JOIN , но (по документация ):

Удебелен акцентът е мой.
Това е причината за вашата грешка. Вие можете поправи го:

FROM  appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...

Но това не беше единственият проблем. Продължете да четете.

Някой може да възрази, че Postgres трябва да види това LATERAL има смисъл само във връзка с таблицата вляво. Но това не е така.

Предположение

Добавих псевдоними на таблици и квалифицирах всички имена на колони според подозрението. Докато се занимавах с това, опростих препратките към JSON и отрязах някои шумове. Тази заявка все още е неправилна :

SELECT i.data ->> 'id'          AS id,
       i.data ->> 'name'        AS name,
       i.data ->> 'curator'     AS curator,
       i.data ->  '$isValid'    AS "$isValid",
       i.data ->  'customer'    AS customer,
       i.data ->  '$createdTS'  AS "$createdTS",
       i.data ->  '$updatedTS'  AS "$updatedTS",
       i.data ->  '$isComplete' AS "$isComplete",
       count(k.keys)::numeric   AS "numProducts",
       u.created_at
FROM   appointment_intakes i
     , jsonb_object_keys(i.data -> 'products') AS k(keys)
JOIN   appointment_intake_users u ON u.appointment_intake_id = i.id
#{where_clause}
GROUP  BY i.id

Необработена заявка

Въз основа на горното и някои други предположения, решението може да бъде преброяването да се извърши в подзаявка:

SELECT i.data ->> 'id'          AS id,
       i.data ->> 'name'        AS name,
       i.data ->> 'curator'     AS curator,
       i.data ->  '$isValid'    AS "$isValid",
       i.data ->  'customer'    AS customer,
       i.data ->  '$createdTS'  AS "$createdTS",
       i.data ->  '$updatedTS'  AS "$updatedTS",
       i.data ->  '$isComplete' AS "$isComplete",
       (SELECT count(*)::numeric
        FROM   jsonb_object_keys(i.data -> 'products')) AS "numProducts",
       min(u.created_at)        AS created_at
FROM   appointment_intakes i
JOIN   appointment_intake_users u ON u.appointment_intake_id = i.id
--     #{where_clause}
GROUP  BY i.id;

Тъй като имате нужда само от броя, преобразувах вашия LATERAL присъединете към корелирана подзаявка, като по този начин избягвате различните проблеми, произтичащи от комбинирането на множество 1:n съединявания. Още:

Виетрябвате за да избегнете правилно идентификаторите, използвайте подготвен израз и предавайте стойности като ценности. Не свързвайте стойности в низа на заявката. Това е покана за случайни грешки или SQL инжектиране атаки. Скорошен пример за PHP:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Последователността на хибернация не е генерирана

  2. Използване на sqldf и RPostgreSQL заедно

  3. SQL:Обратно транспониране на таблица

  4. Настройка на Django:psycopg2.OperationalError:FATAL:Неуспешно удостоверяване на партньор за потребител indivo

  5. PostgreSQL:Създаване на индекс за дължината на всички полета на таблицата