Автор Тема: Хитрый Запрос ---  (Прочитано 2337 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Dolce

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 2
  • +0/-0
  • 0
    • Просмотр профиля
    • http://clops.livejournal.com/
Хитрый Запрос ---
« : 09 Сентября 2003, 17:51:56 »
Значится так, дамы и господа, в моём относительно простеньком движке есть система версий документов, которую я использую для создания многоязычный сайтов. Логика простая, при запросе страницы я проверяю, есть ли странница в СУБД на запрашиваемом языке, если нет, то выдаю дефолтную. При работе с отдельными страницами – это просто. Более сложные задачи это:

    * Постройка Меню

    * Постройка «breadcrumbs»

    * Списки материалов

Например, не все части сайта будут переведены, а посему меню надо будет составлять из разных языковых контентов. Та же проблема касается построения карты сайта.

Несущей таблицей системы является таблица-стрелочник, со следующей структурой:

Create table nodemap(nodeid int unsigned NOT NULL, version int unsigned NOT NULL, object int unsigned NOT NULL, description varchar(255) NOT NULL DEFAULT ‘n/a’);

Предположим, что в ней находится следующий контент:

+--------+---------+--------+-------------+
| nodeid | version | object | description |
+--------+---------+--------+-------------+
|     1  |    1    |    1   | about us    |
|     1  |    2    |    2   | про нас     |
|     2  |    1    |    3   | clients     |
|     3  |    1    |    4   | products    |
|     3  |    2    |    5   | решения     |
|     4  |    1    |    6   | contacts    |
+--------+---------+--------+-------------+

Задача такова, что надо одним запросом получить записи из таблицы с уникальными nodeid отдавая приоритет версии 2, в случае её отсутствия возвращать запись версии 1. Пока мне в голову пришло только такое решение:

SELECT DISTINCT a.nodeid, IF(b.version IS NULL,a.version ,b.version), IF(b.version IS NULL,a.object,b.object), IF(b.version IS NULL,a.description ,b.description) FROM `nodemap` a LEFT JOIN `nodemap` b ON (b.nodeid = a.nodeid AND b.version = 2)

Но, думаю, понятно, что данное решение начнёт давать плохие результаты при, скажем, 50 000 записях в таблице. Может кто знает как это сделать с помощью простой группировки данных?

Оффлайн Alexandr

  • Фанат форума
  • Ветеран
  • *****
  • Сообщений: 865
  • +0/-0
  • 0
    • Просмотр профиля
    • http://gtp.hobi.ru
Хитрый Запрос ---
« Ответ #1 : 10 Сентября 2003, 17:05:42 »
Цитировать
Dolce:
Но, думаю, понятно, что данное решение начнёт давать плохие результаты при, скажем, 50 000 записях в таблице.

Не думаю. Будет всё ок.
Создай ещё индекс
ALTER TABLE nodemap ADD PRIMARY KEY (nodeid, version);
Тогда всё точно будет летать...

Кстати, конструкцию:
Цитировать
Dolce:
IF(b.version IS NULL,a.version ,b.version),

можно заменить на
IFNULL(b.version, a.version)

А вообще я бы сделал след. структуру:
nodeid | description_ru | description_eng
А выбирал бы (напр. eng - default)
SELECT IFNULL(description_$lang, description_eng)
Kiss my CSS
Pусские gtp gp3 ( midi + tab ) -   - Все для Авто.

Оффлайн Dolce

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 2
  • +0/-0
  • 0
    • Просмотр профиля
    • http://clops.livejournal.com/
Хитрый Запрос ---
« Ответ #2 : 10 Сентября 2003, 17:08:06 »
Да, но кол-во языков не ограничено! =)) а за IF - псибы =))

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28