SQLinfo.ru - Все о MySQL Highload++ Junior 2017

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 28.05.2016 18:25:59

remenikomer
Участник
Зарегистрирован: 28.05.2016
Сообщений: 19

Как вывести заполненные списки (страна, регион, город) по id города?

Голову ломаю уже несколько дней.
Необходимо в форме редактирования вывести сразу три списка "локаций": страны - регионы - города.
Пример прикреплен.
Особенность: из базы берется id города. Необходимо сделать SQL-запрос, который бы помог сформировать такие списки. В каждом списке только нужные значения. Например,
- в странах: все страны
- в регионах: регионы выбранной страны
- в городах: города из выбранного региона

Не могу даже понять, в каком виде нужно получить данные из БД, чтобы передать в php.
Таблицы такие:
db_country: id, name
db_region: id, name, countryid
db_town: id, name, regionid

Неактивен

 

#2 28.05.2016 18:41:56

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2027

Re: Как вывести заполненные списки (страна, регион, город) по id города?

SELECT `id`, `name` FROM `db_country`;
SELECT `id`, `name` FROM `db_region` WHERE `country_id` = ID_ВЫБРАННОЙ_СТРАНЫ;
SELECT `id`, `name` FROM `db_town` WHERE `region_id` = ID_ВЫБРАННОГО_РЕГИОНА;


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#3 28.05.2016 18:56:49

remenikomer
Участник
Зарегистрирован: 28.05.2016
Сообщений: 19

Re: Как вывести заполненные списки (страна, регион, город) по id города?

deadka написал:

SELECT `id`, `name` FROM `db_country`;
SELECT `id`, `name` FROM `db_region` WHERE `country_id` = ID_ВЫБРАННОЙ_СТРАНЫ;
SELECT `id`, `name` FROM `db_town` WHERE `region_id` = ID_ВЫБРАННОГО_РЕГИОНА;

Правда немного не так должно быть, т.к. известно только id города, поэтому нужен подзапрос на получение region_id.
ну так-то я знаю. А одним запросом это реально?
Не могу представить таблицу правда. Но говорят, можно.
Или нерационально?

Отредактированно remenikomer (28.05.2016 18:58:58)

Неактивен

 

#4 28.05.2016 19:23:52

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2027

Re: Как вывести заполненные списки (страна, регион, город) по id города?

Заменить точку с запятой на union, полУчите одним запросом, а не тремя.
Насчет рационально - Вы приведите пример выборки, которую хотите получить. И данные, которые Вам известны.


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#5 28.05.2016 20:11:35

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 161

Re: Как вывести заполненные списки (страна, регион, город) по id города?

Возможно так?

SELECT c.`id`, c.`name`, r.`id`, r.`name`, t.`id`, t.`name`,
FROM `db_country` с
  JOIN `db_region` r ON r.`country_id` = c.ID
  JOIN `db_town` t ON t.`region_id` = r.ID
WHERE c.id IN (1, 3, 7, ...);

Но deadka прав, непонятно что нужно получить в итоге.

Неактивен

 

#6 28.05.2016 23:41:09

remenikomer
Участник
Зарегистрирован: 28.05.2016
Сообщений: 19

Re: Как вывести заполненные списки (страна, регион, город) по id города?

klow написал:

Возможно так?

SELECT c.`id`, c.`name`, r.`id`, r.`name`, t.`id`, t.`name`,
FROM `db_country` с
  JOIN `db_region` r ON r.`country_id` = c.ID
  JOIN `db_town` t ON t.`region_id` = r.ID
WHERE c.id IN (1, 3, 7, ...);

Но deadka прав, непонятно что нужно получить в итоге.

примерно такое и нужно, наверно.
Дело в том, что я сам не могу понять, что нужно smile как бы это бредово не звучало.
Но попробую из далека.
У меня все города в одной таблице, как категории, у всех свой id и parentid. Так формируется многомерный массив. На основе id города можно получить в столбце всех родителей (указаны через запятую у каждой записи, город или регион, без разницы), либо перебором большого массива в php. Также есть столбец со всеми дочерними "локациями".
Но есть проблема в такой реализации - массив получается очень большой, чтобы его формировать в переменную, порядка 10Мб. И это грузит сервер.
А без массива не получалось вывести адрес: страна/регион/город у каждого объекта. Т.е. на страницу, например, 50 объектов и нужно было сделать 3 запроса для каждого объекта. А это получалось уже 150 запросов за раз. Как-то некрасиво. Посоветовали таблицу разнести на три. Вот и возник другой вопрос, как вывести списки в форме редактирования.
Теперь по примеру запроса выше.
Он выводит все страны, регионы, города. Получается, что из него нужно вырезать все города, кроме тех, что находятся в выбранном регионе (во втором выпадающем списке формы). Я думаю, что это сократить кол-во строк и нагрузку на сервер, т.к. сейчас получается 1000 строк (со всеми городами).
Я примерно сделал запрос, как смог, он урезал кол-во строк до 103. У других областей просто пишет null. Но есть другая проблема: выполняться он стал 2,5 секунды smile


SELECT c.id, c.name, r.id, r.name, t.id, t.name
FROM `db_country` c
  JOIN `db_region` r ON r.`countryid` = c.ID
  LEFT OUTER JOIN `db_town` t ON t.`regionid` = r.id
  AND t.regionid = (SELECT t.regionid FROM `db_town` t WHERE t.id=870 )
WHERE c.id IN ('1')
 


Поэтому, если нельзя реализовать одним запросом, то буду тогда тройным делать. Редактирование формы все таки не каждую секунду происходит, нагрузка не скажется. Тем более, что в запрос выше нужно еще вставить вместо единицы IN ('1') id страны, которую также нужно сначала получить. В общем, я так думаю, уже извращения начинаются smile Да?

Отредактированно remenikomer (28.05.2016 23:42:59)


Прикрепленные файлы:
Attachment Icon таблица городов.jpg, Размер: 63,372 байт, Скачано: 56

Неактивен

 

#7 28.05.2016 23:46:59

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2027

Re: Как вывести заполненные списки (страна, регион, город) по id города?

Запрос

SELECT t.regionid FROM `db_town` t WHERE t.id=870

однозначно стоит вынести наружу и в Ваш большой запрос подставлять полученное значение, это и запрос упростит, и будет меньше сбивать с толку планировщик.
Ну и индексы на тех полях, где идет связывание в JOIN тоже нужны, если их еще нет.
Делать одним запросом - зачем это, если тремя быстрее получается? Тут мерить время надо уже, и исходя из этого решать - один запрос или три.


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#8 29.05.2016 00:12:16

remenikomer
Участник
Зарегистрирован: 28.05.2016
Сообщений: 19

Re: Как вывести заполненные списки (страна, регион, город) по id города?

deadka написал:

Запрос

SELECT t.regionid FROM `db_town` t WHERE t.id=870

однозначно стоит вынести наружу и в Ваш большой запрос подставлять полученное значение, это и запрос упростит, и будет меньше сбивать с толку планировщик.
Ну и индексы на тех полях, где идет связывание в JOIN тоже нужны, если их еще нет.
Делать одним запросом - зачем это, если тремя быстрее получается? Тут мерить время надо уже, и исходя из этого решать - один запрос или три.

Я еще не насколько хорошо знаю MySQL, чтобы знать тонкости, планировщики, индексы и т.п. smile Я в пределах простых запросов делаю + в dbForge сразу мастерю сложное, методом тыка smile когда не хватает знаний
Если вынести условие, то выводятся только выбранный регион и его города, без остальных регионов.
В общем, убедили. Буду отдельными запросами. Спасибо!

Неактивен

 

#9 29.05.2016 19:33:25

remenikomer
Участник
Зарегистрирован: 28.05.2016
Сообщений: 19

Re: Как вывести заполненные списки (страна, регион, город) по id города?

я все о том же. Пока вопрос с разбивкой на таблицы не закончен, т.к. нужно править много php-когда, то думал сделать временное решение.
Задача: получить поля: страна, регион, город, чтобы подставить их в полный адрес.
Есть таблица где все локации, как категории, связка через parentid.
Есть поле arrparentid. В нем сохранены все родители через запятую. Например для Москвы (0,1,214) - это id Россия (1), Московская область (214).
Была мысля получить сначала всех родителей, а затем этот список подставить в условие поиска через IN, чтобы получить уже родителей (страну, регион).
Но результат выборки получается подзапроса:

SELECT db_area.arrparentid FROM db_area WHERE db_area.areaid = 870

не строки "0","1","214", а одна строка "0,1,214". Соответственно в условие IN попадает одна переменная, который в таблице не находит:


SELECT areaname FROM db_area WHERE areaid IN(
    SELECT db_area.arrparentid FROM db_area WHERE db_area.areaid = 870
)
 

Можно как-то в MySQL эту проблему обойти, разбить на переменные или еще как-то?

Неактивен

 

#10 29.05.2016 20:31:23

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 161

Re: Как вывести заполненные списки (страна, регион, город) по id города?

Используйте  find_in_set, но про индексы забудьте.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson