помогите подправить/составить запрос MySQL

Статус
В этой теме нельзя размещать новые ответы.

chang

Постоялец
Регистрация
20 Ноя 2009
Сообщения
363
Реакции
118
есть таблица
Код:
mysql> select * from location_copy;
+----+-----------+----------+-----------+
| id | name      | id_rajon | id_oblast |
+----+-----------+----------+-----------+
|  1 | olast_1   |     NULL |      NULL |
|  2 | oblast_2  |     NULL |      NULL |
|  3 | rajon_1   |     NULL |         1 |
|  4 | rajon_2   |     NULL |         2 |
|  5 | poselok_1 |        3 |         1 |
|  6 | poselok_2 |        4 |         1 |
+----+-----------+----------+-----------+
нужно получить данные в следующем формате
Код:
+----+-----------+---------+----------+
| id | поселок   | раен    | область  |
+----+-----------+---------+----------+
|  1 | NULL      | NULL    | olast_1  |
|  2 | NULL      | NULL    | oblast_2 |
|  3 | NULL      | rajon_1 | olast_1  |
|  4 | NULL      | rajon_2 | oblast_2 |
|  5 | poselok_1 | rajon_1 | olast_1  |
|  6 | poselok_2 | rajon_2 | olast_1  |
+----+-----------+---------+----------+
данного результата добился следующим запросом,
но походу так делать полный маразм

PHP:
 SELECT
    t1.id,
    null as 'поселок',
    null as  'раен',
    t1.name as  'область'
  FROM location_copy as t1
  WHERE (t1.id_rajon IS NULL
  AND t1.id_oblast IS NULL)
    UNION
  SELECT
    t1.id,
        null as  'поселок',
        t1.name as 'раен',
        t2.name as 'область'
    FROM location_copy as t1
    LEFT JOIN location_copy as t2
    ON t1.id_oblast = t2.id
  WHERE t1.id_rajon IS NULL
    AND t1.id_oblast IS NOT NULL
UNION
 SELECT
  t1.id,
      t1.name as 'поселок',
      t2.name as  'раен',
      t3.name as 'область'
  FROM location_copy as t1
  LEFT JOIN  location_copy  as t2
  ON t1.id_rajon = t2.id
  LEFT JOIN  location_copy as t3
  ON t1.id_oblast = t3.id
WHERE (t1.id_rajon  and t1.id_oblast ) is not NULL;
структура таблицы для тестов
PHP:
CREATE TABLE location_copy(
  id INT(11) NOT NULL AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL COMMENT 'название',
  id_rajon INT(11) DEFAULT NULL COMMENT 'район',
  id_oblast INT(11) DEFAULT NULL COMMENT 'область',
  PRIMARY KEY (id),
  INDEX FK_location_rajon_id2 (id_rajon),
  INDEX FK_location_region_id (id_oblast)
)
ENGINE = INNODB
AUTO_INCREMENT = 1
CHARACTER SET utf8
COLLATE utf8_general_ci;
INSERT INTO location_copy VALUES 
  (1, 'olast_1', NULL, NULL),
  (2, 'oblast_2', NULL, NULL),
  (3, 'rajon_1', NULL, 1),
  (4, 'rajon_2', NULL, 2),
  (5, 'poselok_1', 3, 1),
  (6, 'poselok_2', 4, 1);
 
как-то мало здесь спецов по sql ... толи всем впадло что-то делать :)

короч вот последний вариант.... вродь нехило упростилось ... если кто знает лучшее решение - буду рад увидеть

PHP:
SELECT
	p.id,
	IF(r.name IS NULL, NULL, p.name) AS poselek,
	IF(o.name IS NULL, NULL, IFNULL(r.name,p.name)) AS rajon,
	IFNULL(o.name,p.name) AS oblast
FROM location_copy p
	LEFT JOIN location_copy r ON p.id_rajon=r.id
	LEFT JOIN location_copy o ON p.id_oblast=o.id
 
есть таблица
нужно получить данные в следующем формате
Вы уж простите, а вы уверены, что вам надо получить данные именно в "следующем формате"? Возможно в таком будет лучше?
Код:
+----+-----------+---------+----------+
| id | поселок   | раен    | область  |
+----+-----------+---------+----------+
|  1 | poselok_1 | rajon_1 | olast_1  |
|  2 | poselok_2 | rajon_2 | olast_1  |
+----+-----------+---------+----------+
---------------------------------------
SELECT l0.name AS name, l1.name AS rajoin, l2.name AS oblast
FROM location_copy l0, location_copy l1, location_copy l2
WHERE l0.id_rajon = l1.id
AND l1.id_oblast = l2.id

И если не секрет, то зачем хранить для каждой записи и ИДрайона и ИДобласти?
 
Вы уж простите, а вы уверены, что вам надо получить данные именно в "следующем формате"? Возможно в таком будет лучше?

уверен конечно =)


И если не секрет, то зачем хранить для каждой записи и ИДрайона и ИДобласти?

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