Ошибка в элементе предложения from неверная ссылка на таблицу

Prtoy

3 / 3 / 3

Регистрация: 01.06.2016

Сообщений: 299

1

Объединение запросов

07.03.2017, 11:38. Показов 16858. Ответов 14

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Здравствуйте.
Имеются несколько запросов к БД:

SQL
1
2
SELECT sp_struc.naz FROM queue.sp_que, isp.sp_struc 
WHERE sp_que.ids = sp_struc.ids ORDER BY sp_que.ids;

Возвращает наименования офисов организации, например:
Офис 1
Офис 2
Офис 3
Офис 4

SQL
1
2
SELECT COUNT(*) FROM queue.onpriem, queue.sp_que 
WHERE onpriem.idq = sp_que.id GROUP BY sp_que.id ORDER BY sp_que.ids;

Возвращает количество людей на приёме каждом из этих офисов, например:
1
3
5
4

SQL
1
2
SELECT COUNT(*) FROM queue.que, queue.sp_que 
WHERE que.idq = sp_que.id GROUP BY sp_que.id ORDER BY sp_que.ids;

Возвращает количество людей в эл. очереди в каждом из офисов, аналогично предыдущему примеру

SQL
1
2
SELECT COUNT(*) FROM queue.stat WHERE (dat_p>='2017-03-02') 
AND rez=1 GROUP BY idq ORDER BY idq;

Возвращает количество принятых людей по каждому из офисов за выбранную дату

Подскажите пожалуйста, как всё это объединить в один запрос, чтобы в итоге получилась одна таблица с названиями офисов и показателями по ним из примеров выше? Пробовал использовать UNION ALL, но выдало ошибку.



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

07.03.2017, 11:38

Ответы с готовыми решениями:

Объединение 2 запросов или 1 запрос
Доброго времени суток! Есть 3 таблицы: adverts(id, title, creation_date), status(id, title),…

Объединение запросов
Добрый день.

имеется запрос:
select c.id,t.mind,c.name from table1 c
join table2 t on…

Объединение запросов
Доброго времени суток!!! Как можно объединить эти два запроса в один.
USE " . $_SESSION . ";…

объединение запросов
можно ли вот эти запросы объединить в один

if($row=mysql_fetch_array(mysql_query("SELECT word…

14

1213 / 938 / 373

Регистрация: 02.09.2012

Сообщений: 2,862

07.03.2017, 14:53

2

Чтобы связать все эти запросы в одно целое, нужно понимать как между собой связаны все упомянутые таблицы. Нужна модель данных. Того, что написано в разрозненных запросах, недостаточно.



0



3 / 3 / 3

Регистрация: 01.06.2016

Сообщений: 299

13.03.2017, 13:57

 [ТС]

3

grgdvo, из PostgreSQL это можно как-то извлечь?



0



1213 / 938 / 373

Регистрация: 02.09.2012

Сообщений: 2,862

13.03.2017, 15:12

4

Да, ищите/ставьте любой понравившийся «Data Modeler» с функцией «Reverse Engineering». Начать поиск можно отсюда.



0



3 / 3 / 3

Регистрация: 01.06.2016

Сообщений: 299

13.03.2017, 15:40

 [ТС]

5

grgdvo, вот, надеюсь, это то, что нужно.



0



grgdvo

1213 / 938 / 373

Регистрация: 02.09.2012

Сообщений: 2,862

14.03.2017, 15:44

6

Ну не очень диаграмма. Начните вот с этой версии запроса.

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
sp_struc.naz,
COUNT(onpriem.id),
COUNT(que.id),
COUNT(stat.id)
FROM
isp.sp_struc,
queue.sp_que, 
queue.onpriem,
queue.que,
queue.stat
WHERE
sp_struc.ids = sp_que.ids AND
sp_que.id = onpriem.idq AND
sp_que.id = que.idq AND
sp_que.id = stat.idq AND stat.dat_p>='2017-03-02' AND stat.rez=1
GROUP BY
sp_struct.naz
ORDER BY sp_que.ids



0



Prtoy

3 / 3 / 3

Регистрация: 01.06.2016

Сообщений: 299

14.03.2017, 17:30

 [ТС]

7

grgdvo,
Не получилось.
ОШИБКА: таблица «sp_struct» отсутствует в предложении FROM
LINE 18: sp_struct.naz

Добавлено через 15 минут
По этой ошибке разобрался,

SQL
1
GROUP BY sp_struc.naz

вместо

SQL
1
GROUP BY sp_struct.naz

Но после этого вылезла другая ошибка:
«ОШИБКА: столбец «sp_que.ids» должен фигурировать в предложении GROUP BY или использоваться в агрегатной функции»

Добавил в GROUP BY столбец sp_que.ids (GROUP BY sp_struc.naz, sp_que.ids) — после этого запрос сработал, но выдал какие-то нереальные данные, плюс одинаковые во всех столбцах. Плюс, исчез один из офисов. Если поменять местами столбцы (GROUP BY sp_que.ids, sp_struc.naz) — то выходят все офисы, но данные также нереальные и одинаковые.

Добавлено через 17 минут
Ещё пытался с джойнами сделать, хотя бы первые два запроса, примерно так:

SQL
1
2
3
4
5
6
SELECT sp_struc.naz, COUNT(*) 
FROM queue.sp_que, isp.sp_struc 
LEFT OUTER JOIN queue.onpriem ON sp_que.ids = sp_struc.ids
WHERE sp_que.ids = sp_struc.ids 
GROUP BY sp_struc.naz
ORDER BY sp_que.ids

Но вылазит вот такая ошибка:
ОШИБКА: в элементе предложения FROM неверная ссылка на таблицу «sp_que»
HINT: Таблица «sp_que» присутствует в запросе, но сослаться на неё из этой части запроса нельзя.



0



grgdvo

1213 / 938 / 373

Регистрация: 02.09.2012

Сообщений: 2,862

15.03.2017, 05:11

8

JOIN конструкция должна быть «цельной». В подвыражении ON вы не можете использовать другие таблицы кроме тех, которые перечислены слева и справа от JOIN. Запятая не в счет, это уже другой вид соединения других таблиц.

Вся проблема в соединениях связана с тем, что модель связей таблиц четко не прописана. У вас в принципе queue.onpriem висячая таблица, непонятно как она с кем связана. Также по смыслу непонятно, что таблицы обозначают и какая смысловая связь между ними. Если главная сущность sp_struc — офис (больница), в больнице существует одна (может больше) электронная очередь — queue.sp_que, в настоящий момент на приеме есть пациенты из такой-то очереди (может быть нескольких очередей) — queue.onpriem, то вероятно можно запрос так построить

SQL
1
2
3
4
5
6
7
SELECT
sp_struc.naz, COUNT(onpriem.id)
FROM
isp.sp_struc INNER JOIN queue.sp_que ON sp_struc.ids = sp_que.ids
LEFT OUTER JOIN queue.onpriem ON sp_que.id = onpriem.idq
GROUP BY sp_struc.naz
ORDER BY sp_que.ids;

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



1



3 / 3 / 3

Регистрация: 01.06.2016

Сообщений: 299

15.03.2017, 08:14

 [ТС]

9

grgdvo, Так тоже не получилось, ОШИБКА: столбец «sp_que.ids» должен фигурировать в предложении GROUP BY или использоваться в агрегатной функции.

Да, не имея самой базы под рукой, сложно понять… Попробую словами объяснить.
isp.sp_struc — это таблица с оргиназациями (оттуда нам нужны только их названия — sp_struc.naz)
queue.sp_que — это таблица с электронными очередями (названий организаций тут нет, зато есть ид организаций, к которым привязываются очереди — ids).
queue.onpriem — таблица со значениям о тех, кто на приёме
queue.que — таблица с текущей очередью
queue.stat — статистика (сколько кого было в очередях, на приёме, и т.д.)
onpriem.idq, que.idq — номера очередей, они равны sp_que.id

Можно конечно сделать модель всей базы данных, там очень много всяких таблиц и зависимостей, но теоретически этих двух должно хватать.



0



1213 / 938 / 373

Регистрация: 02.09.2012

Сообщений: 2,862

15.03.2017, 10:13

10

вот как раз для onpriem, que и stat и не хватает описания связующих полей. какие поля в этих таблицах отвечают за связь с электронной очередью???

а с ОШИБКОЙ это я сглупил, копипастил запрос с предыдущего поста и не исправил. Конечно должна быть сортировка по sp_struc.naz, т.е. ORDER BY sp_struc.naz



1



Prtoy

3 / 3 / 3

Регистрация: 01.06.2016

Сообщений: 299

15.03.2017, 11:19

 [ТС]

11

grgdvo, да, так получилось. Это мы узнали сколько где на приёме людей. Таким же образом остальные запросы можно присобачить?

sp_que.id = onpriem.idq = que.idq = stat.idq — это все номера электронных очередей, они и связаны между собой.

Добавлено через 54 минуты
Попробовал вот так:

SQL
1
2
3
4
5
6
7
8
SELECT
sp_struc.naz, COUNT(onpriem.id) AS naprieme, COUNT(que.id) AS vocheredi
FROM
isp.sp_struc INNER JOIN queue.sp_que ON sp_struc.ids = sp_que.ids
LEFT OUTER JOIN queue.onpriem ON sp_que.id = onpriem.idq
LEFT OUTER JOIN queue.que ON sp_que.id = que.idq
GROUP BY sp_struc.naz
ORDER BY sp_struc.naz;

Запрос срабатыает, но снова показывает какую-то чушь…



0



grgdvo

1213 / 938 / 373

Регистрация: 02.09.2012

Сообщений: 2,862

15.03.2017, 15:52

12

Лучший ответ Сообщение было отмечено Prtoy как решение

Решение

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SELECT
  sp_struc.naz,
  SUM(cnt_onpriem),
  SUM(cnt_que),
  SUM(cnt_stat)
FROM
  isp.sp_struc,
  (SELECT
    sp_que.ids, 
    (SELECT COUNT(*) FROM queue.onpriem WHERE sp_que.id = onpriem.idq) cnt_onpriem,
    (SELECT COUNT(*) FROM queue.que  WHERE sp_que.id = que.idq) cnt_que,
    (SELECT COUNT(*) FROM queue.stat WHERE sp_que.id = stat.ids) cnt_stat
  FROM
    queue.sp_que) q1
WHERE
  sp_struc.ids = q1.ids
GROUP BY
  sp_struc.naz
ORDER BY
  sp_struc.naz;

Не самый оптимальный план запроса будет при такой форме, но что-то я сходу не соображу, как можно совместить COUNT и SUM.



1



Prtoy

3 / 3 / 3

Регистрация: 01.06.2016

Сообщений: 299

15.03.2017, 16:03

 [ТС]

13

grgdvo, спасибо большое. Только чуть-чуть подправил, в 12 строке WHERE sp_que.id = stat.idq и надо было за выбранную дату, с определённым параметром (rez = 1), т.е. 12 строка получилась:

SQL
1
(SELECT COUNT(*) FROM queue.stat WHERE sp_que.id = stat.idq AND (dat_p>='2017-03-15') AND rez=1) cnt_stat

А что делает SUM и чем от COUNT отличается? Раньше не сталкивался…



0



1213 / 938 / 373

Регистрация: 02.09.2012

Сообщений: 2,862

15.03.2017, 16:14

14

COUNT(*) вы просто считаете записи, которые выбрали из таблицы
SUM — суммирует числовые значения.
Идея такая. Сначала в подзапросе q1 подсчитываем все количества записей из зависимых таблиц. Если ничего не выбираем из зависимых таблиц, то COUNT(*) насчитает 0. Далее уже аккумулированные данные связываем с таблицей имен и поскольку очередей для каждого офиса потенциально может быть больше одной, то все посчитанные количества надо просуммировать. В итоге получается не самый удачный план запроса, который будет долго выбирать на больших объемах данных.
Интуитивно мне кажется можно как-то совместить SUM и OUTER JOIN для всех пяти таблиц в один запрос, чтобы получился оптимальный план запроса, но я уже пас на сегодня работать. Хотите, исследуйте производительность самостоятельно.



0



3 / 3 / 3

Регистрация: 01.06.2016

Сообщений: 299

15.03.2017, 16:31

 [ТС]

15

Спасибо. Срабатывает быстро, таблицы с очередями вряд ли вырастут настолько, чтобы нужно было данный запрос оптимизировать… Сам вряд ли справлюсь, нужно более углублённо изучать SQL, и скорее всего, начинать с нуля

Спасибо ещё раз за помощь.



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

15.03.2017, 16:31

15

Причина очень проста. Формально comma-style join — это алиас CROSS JOIN. Но есть подвох — приоритет comma-style join ниже приоритета explicit join. И выражение источника данных, если расставить скобки в соответствии с приоритетом, получится такое:

from
table1 , ( table2
           left join table1 h on table1.id = h.id
           left join table2 s on table2.id = s.id )

Вот теперь прекрасно видно, что внутри скобки о существовании где-то там снаружи table1 ничего не известно.

Правильно — забыть НАВСЕГДА о возможности использовать запятую. И писать вот так:

FROM table1 
CROSS JOIN table2
LEFT JOIN table1 h ON table1.id = h.id
LEFT JOIN table2 s ON table2.id = s.id

PS. Если всё же без comma-style жизнь не мила, можно поступить так, как обычно делают для явного задания приоритета. То есть добавить задающие приоритет скобки:

FROM (table1 , table2)
LEFT JOIN table1 h ON table1.id = h.id
LEFT JOIN table2 s ON table2.id = s.id

Теперь всё в порядке — сначала выполнится запятая, а потом к результату будут LEFT JOIN остальные две таблицы.

Запрос который работает

select analytics.public.client.name, analytics.public.client.whatsapp, analytics.public.incoming_request.utm_source
from client
inner join incoming_request
on client.id = incoming_request.client_id;

Добавил AS и этот же запрос перестал работать

select analytics.public.client.name, analytics.public.client.whatsapp, analytics.public.incoming_request.utm_source
from client as c
inner join incoming_request as ir
on c.id = ir.client_id

Ну вот как так???

Код ошибки

[42P01] ОШИБКА: в элементе предложения FROM неверная ссылка на таблицу "client" Подсказка: Возможно, предполагалась ссылка на псевдоним таблицы "c". Позиция: 8

Но там нет, я перепроверил

задан 16 авг 2021 в 19:08

Дядя Фёдор's user avatar

Для этого случая даже специальную отдельную подсказку выводим

 * If we found a match that has an alias and the alias is visible in the
 * namespace, then the problem is probably use of the relation's real name
 * instead of its alias, ie "SELECT foo.* FROM foo f". This mistake is
 * common enough to justify a specific hint.

Запрос вида

SELECT foo.column_name FROM foo as f

Ошибочен. Если вы пишете алиас — то и далее в запросе должны использовать этот алиас, т.е.

SELECT f.column_name FROM foo as f

Поскольку отношения foo более в дереве запроса нет, вы указали ему псевдоним.

PS: указывать имена полей, начиная с имени базы — довольно странная затея. Тогда уж и имена таблиц пишите так же, и все операторы тоже fully qualified, а то как-то непоследовательно.

ответ дан 16 авг 2021 в 19:34

Мелкий's user avatar

МелкийМелкий

21.3k3 золотых знака27 серебряных знаков53 бронзовых знака

2

I have the following SQL (PostgreSQL) query:

SELECT ff.*, fp.*
FROM fibra ff, fibra fp

JOIN cables cp ON fp.cable_id = cp.id
LEFT OUTER JOIN terceiro  ced_pai ON ced_pai.id = cp.cedente_id
LEFT OUTER JOIN terceiro tp ON tp.id = fp.terceiro_id

JOIN cables cf ON ff.cable_id = cf.id
LEFT OUTER JOIN terceiro ced_f ON ced_f.id = cf.cedente_id
LEFT OUTER JOIN terceiro tf ON tf.id = ff.terceiro_id

where ff.fibra_pai_id = fp.id 
AND ff.cable_id IN (8,9,10) 
AND fp.cable_id IN (8,9,10)

But it’s giving me this error:

ERROR:  invalid reference to FROM-clause entry for table "ff"
LINE 8:  JOIN cables cf ON ff.cable_id = cf.id
           ^
HINT:  There is an entry for table "ff", but it cannot be referenced from this part of the query.

********** Error **********

ERROR: invalid reference to FROM-clause entry for table "ff"
SQL state: 42P01
Hint: There is an entry for table "ff", but it cannot be referenced from this part of the query.
Character: 261

Does anyone know what AM I doing wrong ?

asked Nov 8, 2012 at 20:43

lcguida's user avatar

3

You are mixing implicit and explicit JOINs. That’s generally confusing to read, and leads to unexpected order-of-evaluation problems, as you’ve just discovered.

You should consistently use JOIN ... ON syntax everywhere; avoid the legacy FROM table1, table2. If you correct your query to use an explicit JOIN instead of FROM fibra ff, fibra fp, eg FROM fibra ff INNER JOIN fibra fp ON (ff.fibra_pai_id = fp.id) and omit ff.fibra_pai_id = fp.id from the WHERE clause, you should get the expected result.

See this question that A.H. linked to:

Mixing explicit and implicit joins fails with «There is an entry for table … but it cannot be referenced from this part of the query»

Community's user avatar

answered Nov 9, 2012 at 0:53

Craig Ringer's user avatar

Craig RingerCraig Ringer

304k74 gold badges680 silver badges765 bronze badges

3

Convert all the joins in your query to be explicit to avoid the issue you’re having—don’t leave some implicit and others explicit.

This should work:

SELECT ff.*, fp.*
  FROM fibra ff

  JOIN fibra fp ON ff.fibra_pai_id = fp.id 

  JOIN cables cp ON fp.cable_id = cp.id
  LEFT OUTER JOIN terceiro  ced_pai ON ced_pai.id = cp.cedente_id
  LEFT OUTER JOIN terceiro tp ON tp.id = fp.terceiro_id

  JOIN cables cf ON ff.cable_id = cf.id
  LEFT OUTER JOIN terceiro ced_f ON ced_f.id = cf.cedente_id
  LEFT OUTER JOIN terceiro tf ON tf.id = ff.terceiro_id

WHERE
 ff.cable_id IN (8,9,10) 
 AND fp.cable_id IN (8,9,10)

answered Nov 8, 2012 at 20:49

Ray's user avatar

RayRay

40.1k20 gold badges97 silver badges137 bronze badges

1

In my case the problem was that I forgot I had assigned my tables to a particular schema and needed to reference those e.g:

select r.*
from my_schema.resources r

answered Aug 25, 2021 at 16:08

Jonathan's user avatar

JonathanJonathan

10.9k8 gold badges63 silver badges79 bronze badges

Database Exception – yiidbException
SQLSTATE[42P01]: Undefined table: 7 ERROR: invalid reference to FROM-clause entry for table "ct"
LINE 8: inner join generate_subscripts(ct.conkey, 1) as s on 1=1
^
HINT: There is an entry for table "ct", but it cannot be referenced from this part of the query.
The SQL being executed was: select
a.attname as column_name,
fc.relname as foreign_table_name,
fns.nspname as foreign_table_schema,
fa.attname as foreign_column_name
from
pg_constraint ct
inner join generate_subscripts(ct.conkey, 1) as s on 1=1
inner join pg_class c on c.oid=ct.conrelid
inner join pg_namespace ns on c.relnamespace=ns.oid
inner join pg_attribute a on a.attrelid=ct.conrelid and a.attnum = ct.conkey[s]
left join pg_class fc on fc.oid=ct.confrelid
left join pg_namespace fns on fc.relnamespace=fns.oid
left join pg_attribute fa on fa.attrelid=ct.confrelid and fa.attnum = ct.confkey[s]
where
ct.contype='f'
and c.relname='acc_periode'
and ns.nspname='public'
order by
fns.nspname, fc.relname, a.attnum

Error Info: Array
(
    [0] => 42P01
    [1] => 7
    [2] => ERROR:  invalid reference to FROM-clause entry for table "ct"
LINE 8:     inner join generate_subscripts(ct.conkey, 1) as s on 1=1
                                           ^
HINT:  There is an entry for table "ct", but it cannot be referenced from this part of the query.
)

↵
Caused by: PDOException
SQLSTATE[42P01]: Undefined table: 7 ERROR: invalid reference to FROM-clause entry for table "ct"
LINE 8: inner join generate_subscripts(ct.conkey, 1) as s on 1=1
^
HINT: There is an entry for table "ct", but it cannot be referenced from this part of the query.

in /home/mdmunir/NetBeansProjects/deesoft/development/vendor/yiisoft/yii2/db/Command.php at line 820

I am using postgresql.
Error provide when call $db->getSchema()->getTableSchemas($schemaName)

Понравилась статья? Поделить с друзьями:
  • Ошибка в электронной трудовой книжке как исправить
  • Ошибка в электронной медицинской карте как исправить
  • Ошибка в электронике рулевой колонки
  • Ошибка в электрической цепи что может быть
  • Ошибка в электрической цепи рено сандеро степвей