Форум программистов, компьютерный форум, киберфорум
PostgreSQL
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.74/103: Рейтинг темы: голосов - 103, средняя оценка - 4.74
3 / 3 / 3
Регистрация: 01.06.2016
Сообщений: 307
1

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

07.03.2017, 11:38. Показов 20123. Ответов 14
Метки нет (Все метки)

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

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
Лучшие ответы (1)
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
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,976
07.03.2017, 14:53 2
Чтобы связать все эти запросы в одно целое, нужно понимать как между собой связаны все упомянутые таблицы. Нужна модель данных. Того, что написано в разрозненных запросах, недостаточно.
0
3 / 3 / 3
Регистрация: 01.06.2016
Сообщений: 307
13.03.2017, 13:57  [ТС] 3
grgdvo, из PostgreSQL это можно как-то извлечь?
0
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,976
13.03.2017, 15:12 4
Да, ищите/ставьте любой понравившийся "Data Modeler" с функцией "Reverse Engineering". Начать поиск можно отсюда.
0
3 / 3 / 3
Регистрация: 01.06.2016
Сообщений: 307
13.03.2017, 15:40  [ТС] 5
grgdvo, вот, надеюсь, это то, что нужно.
Вложения
Тип файла: zip Diagram 1.zip (1.65 Мб, 9 просмотров)
0
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,976
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
3 / 3 / 3
Регистрация: 01.06.2016
Сообщений: 307
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
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,976
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
Сообщений: 307
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
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,976
15.03.2017, 10:13 10
вот как раз для onpriem, que и stat и не хватает описания связующих полей. какие поля в этих таблицах отвечают за связь с электронной очередью???

а с ОШИБКОЙ это я сглупил, копипастил запрос с предыдущего поста и не исправил. Конечно должна быть сортировка по sp_struc.naz, т.е. ORDER BY sp_struc.naz
1
3 / 3 / 3
Регистрация: 01.06.2016
Сообщений: 307
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
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,976
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
3 / 3 / 3
Регистрация: 01.06.2016
Сообщений: 307
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
1251 / 967 / 382
Регистрация: 02.09.2012
Сообщений: 2,976
15.03.2017, 16:14 14
COUNT(*) вы просто считаете записи, которые выбрали из таблицы
SUM - суммирует числовые значения.
Идея такая. Сначала в подзапросе q1 подсчитываем все количества записей из зависимых таблиц. Если ничего не выбираем из зависимых таблиц, то COUNT(*) насчитает 0. Далее уже аккумулированные данные связываем с таблицей имен и поскольку очередей для каждого офиса потенциально может быть больше одной, то все посчитанные количества надо просуммировать. В итоге получается не самый удачный план запроса, который будет долго выбирать на больших объемах данных.
Интуитивно мне кажется можно как-то совместить SUM и OUTER JOIN для всех пяти таблиц в один запрос, чтобы получился оптимальный план запроса, но я уже пас на сегодня работать. Хотите, исследуйте производительность самостоятельно.
0
3 / 3 / 3
Регистрация: 01.06.2016
Сообщений: 307
15.03.2017, 16:31  [ТС] 15
Спасибо. Срабатывает быстро, таблицы с очередями вряд ли вырастут настолько, чтобы нужно было данный запрос оптимизировать... Сам вряд ли справлюсь, нужно более углублённо изучать SQL, и скорее всего, начинать с нуля

Спасибо ещё раз за помощь.
0
15.03.2017, 16:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.03.2017, 16:31
Помогаю со студенческими работами здесь

Объединение запросов
Такая ситуация, необходимо вывести 2 столбца, образованные от одной таблицы. Условия образования...

Объединение запросов
Доброго времени суток! Помогите, пожалуйста объеденить два запроса в один $query = "SELECT...

Объединение 2х запросов в 1
Здравствуйте, форумчане! Есть 2 запроса SQL: SELECT `email_admin` FROM `options` WHERE...

Объединение запросов
Доброго времени суток! Помогите связать запросы. В первом считается сумма отгрузок по дням...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru