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

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

07.03.2017, 11:38. Показов 21119. Ответов 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
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.03.2017, 11:38
Ответы с готовыми решениями:

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

Объединение запросов
Добрый день. имеется запрос: select c.id,t.mind,c.name from table1 c join table2 t on t.id=c.id where t.date between...

Объединение запросов
Доброго времени суток!!! Как можно объединить эти два запроса в один. USE " . $_SESSION . "; CREATE TABLE users (id INT(3) UNIQUE...

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

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

Спасибо ещё раз за помощь.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.03.2017, 16:31
Помогаю со студенческими работами здесь

объединение запросов
можно ли вот эти запросы объединить в один if($row=mysql_fetch_array(mysql_query("SELECT word FROM table1 WHERE a='ccc' AND c=200 AND...

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru