Как запросом вывести адрес: страна, город (mysql)

danneo

Честный
Регистрация
13 Ноя 2007
Сообщения
1.527
Реакции
121
Нужно вывести адрес: страна, город.
Есть таблица:
areaid, areaname, arrparentid (через запятую все родители).

SELECT db_area.arrparentid AS arr_parent_id,
( SELECT areaname FROM db_area WHERE areaid IN( arr_parent_id ) )

Например:
arr_parent_id = 0,1,232
При таком запросе выходит две локации - страна, регион. Т.е. 2 строки. Выходит ошибка.
Как их в запросе перевести в строку с запятой или получить только страну, т.е. = 1

И как вообще делаются такие запросы?
 
не понял по данным, у тебя есть таблица, в которой areaid - айди города areaname - название города arrparentid - родитель города(страна)
если так, то откуда получить название страны? есть отдельная таблица? тебе нужен сложный запрос полюбэ.
 
не понял по данным, у тебя есть таблица, в которой areaid - айди города areaname - название города arrparentid - родитель города(страна)
если так, то откуда получить название страны? есть отдельная таблица? тебе нужен сложный запрос полюбэ.
areaid - id, ключ
areaname - название
arrparentid (через запятую id всех родители), например 0,1,232 = 0, 1 - Россия, 232 - Область какая-то.
Как-то ведь выводится из такой таблицы, знаю такие сайты. Да и если просто вывести подзапросом, то выведется 2-3 локации. Далее их можно обработать foreach и составить строку. Но проблема в том, что мне нужно вывести не один объект с адресом (это все работает через подзапрос, как в примере выше), а нужен список объектов и у каждого адрес. В MySQL это нужно как-то сформировать (запрос), а в php уже разбирать его.

И еще почему-то выводит 0 строк такой запрос:
Код:
SELECT *
  FROM db_area
  WHERE db_area.areaid IN(

SELECT db_area.arrparentid
  FROM db_area
  WHERE db_area.areaid = 870
)
Хотя если сначала сделать подзапрос, то там выведет: 0,1,232. Если подставить это значение вместо подзапроса, то результат будет = 2 строки. Вроде все правильно...

Насколько я понял, хорошо подойдет GROUP_CONCAT, но только чет не выходит
 
Последнее редактирование:
Нашел решение, но есть небольшая проблемы.
Вот такой запрос:
Код:
SELECT GROUP_CONCAT( DISTINCT db_area.areaname ORDER BY db_area.areaid ASC SEPARATOR ', ' )
FROM db_area WHERE db_area.areaid IN(
      --- SELECT db_area.arrparentid FROM db_area WHERE db_area.areaid=296
      0,1,219
)

Закомментирована строка
Код:
подзапроса SELECT db_area.arrparentid FROM db_area WHERE db_area.areaid=296
выдает 0,1,219. Это содержание столбца arrparentid у города, т.е. все его родители (страна, регион)
Но если выполнить этот запрос отдельно, не как подзапрос, то он вернет результат: 0,1,219.
И если выполнить большой запрос с цифрами 0,1,219, то весь адрес переведется в строку: страна, регион.
А если раскомментировать подзапрос (убрав явное указание id родителей), то в столбце вернется NULL. Какая-то нестыковка получается с подзапросом.
Может кто подсказать?
 
( SELECT areaname FROM db_area WHERE areaid IN( arr_parent_id ) )

Например:
arr_parent_id = 0,1,232

Неправильно понимаете синтаксис SQL.

IN( arr_parent_id ) будет обработано как "0,1,232"
IN(0,1,232) будет обработано как "0", "1", "232"

Чувствуете разницу?

Решения:
1. Сделать правильно - через дополнительную таблицу - связку
2. Сделать 2 запроса, первый получает "0,1,232", потом сконструировать правильный "0", "1", "232" - не через SQL, а на пыхе, например
 
Неправильно понимаете синтаксис SQL.

IN( arr_parent_id ) будет обработано как "0,1,232"
IN(0,1,232) будет обработано как "0", "1", "232"

Чувствуете разницу?

Решения:
1. Сделать правильно - через дополнительную таблицу - связку
2. Сделать 2 запроса, первый получает "0,1,232", потом сконструировать правильный "0", "1", "232" - не через SQL, а на пыхе, например
Например, выводится список объектов. У каждого объекта получаю arr_parent_id ("0,1,232"), а потом у каждого делаю SQL-запрос. Если 30 объектов на страницу, то это 30 запросов же будет. Это же нагрузка?
А нельзя в mysql сделать что-нибудь с заменой запятых, а затем вывести подзабросом через regexp, без php?
 
А нельзя в mysql сделать что-нибудь с заменой запятых, а затем вывести подзабросом через regexp, без php?

Простой функции разбиения массива по запятой на строки в SQL нет. Есть сложные решения - гуглить "mysql split comma string into rows"
Такие решения появляются то ли от безысходности, то ли от "сильного ума".

РСУБД - это прежде всего отношения. А отношение M:N или 1:N записываются через доп. таблицу - связку. Это будет православным решением с джойнами. То есть избавляемся от колонки с запятыми, и добавляем новую таблицу.

Ну и наполнение такой таблицы можно повесить на триггер и хранимую функцию. Если знаете как.

30 запросов, если они быстрые - фигня.
 
Простой функции разбиения массива по запятой на строки в SQL нет. Есть сложные решения - гуглить "mysql split comma string into rows"
Такие решения появляются то ли от безысходности, то ли от "сильного ума".

РСУБД - это прежде всего отношения. А отношение M:N или 1:N записываются через доп. таблицу - связку. Это будет православным решением с джойнами. То есть избавляемся от колонки с запятыми, и добавляем новую таблицу.

Ну и наполнение такой таблицы можно повесить на триггер и хранимую функцию. Если знаете как.

30 запросов, если они быстрые - фигня.
да я уже думал и не один раз, чтобы сделать страны/области/города на три таблицы. Делал сначала так, потом перевел в три таблицы. Затем, снова в одну. Вс время возникали различные трудности. В нынешнем варианте исполнения их было меньше.
1. Точно уже не помню какие, но вот, для примера: как вывести выпадающие списки стран, областей, городов с выбранным городом? Т.е. три списка, в первом страны с выбранной страной, далее области из выбранной страны, а затем города из выбранной области. Это все дело в форме редактирования объекта. Как примерно выглядит SQL-запрос? У меня в голове только так: запрос select areaid from db where parentid = (select areaid from db where parentid =( select areaid from db where parentid = selected_areaid)). Раньше таким не увлекался, опыта было мало. Сейчас же не знаю, насколько это правильно и удобно.
2. Или еще вариант, вывести адрес объекта. При хранении в одной таблице все выводится рекурсией или через while, т.к. все в одном массиве из одной таблицы.
3. Как вывести объекты, если в фильтре выбрана только область или страна. А у объекта указано id города. Нужно получается сохранять у объекта id страны, области и города?
 
Последнее редактирование:
страны/области/города на три таблицы
Это классика (смотри "нормальная форма"). Какие проблемы с ними были?
Если нужна скорость, то можно пойти на денормализацию, сделав обновление по триггеру. Например в города писать еще один столбец - страну.
выпадающие списки стран, областей, городов с выбранным городом
Страны:
Код:
SELECT * FROM countries
Пользователь выбрал страну, делаем аякс-запрос областей:
Код:
SELECT * FROM regions where country_id = 18
Пользователь выбрал область, делаем аякс-запрос городов:
Код:
SELECT * FROM cities where region_id = 50
Это три последовательных простых запроса, по мере выбора.
вывести адрес объекта
см. JOIN
Как вывести объекты, если в фильтре выбрана только область или страна. А у объекта указано id города. Нужно получается сохранять у объекта id страны, области и города?
см. JOIN
Пример выбора для страны 18
Код:
SELECT * 
FROM countries
JOIN regions ON (regions.country_id = countries.id)
JOIN cities ON (cities.region_id = regions.id)
WHERE countries.id = 18
 
Пользователь выбрал страну, делаем аякс-запрос областей:
SELECT * FROM regions where country_id = 18
Пользователь выбрал область, делаем аякс-запрос городов:
SELECT * FROM cities where region_id = 50
Это три последовательных простых запроса, по мере выбора.
Не то немного. Например, все так прошло. Далее пользователь отправил форму. На сервере обработал и нашлась ошибка в заполнении. Пользователю выводится форма с ранее введенными данными. И нужно вывести все три списка. Ранее я делал так, получал по id в столбце города все id родителей и большой массив перебирал, формируя списки и ставил выделение выбранных значений.
 
Назад
Сверху