Alexander-V-Sh Опубликовано 22 июня, 2006 Жалоба Поделиться Опубликовано 22 июня, 2006 Имеется 2 таблицы: CREATE TABLE `downloads_categories` (`cid` int(11) NOT NULL auto_increment,`title` varchar(50) NOT NULL default '',`cdescription` text NOT NULL,`parentid` int(11) NOT NULL default '0',PRIMARY KEY (`cid`),KEY `cid` (`cid`),KEY `title` (`title`))downloads_categories` VALUES (1, 'Программы', '', 0);downloads_categories` VALUES (2, 'Графика и дизайн', '', 1);downloads_categories` VALUES (3, 'Графика', '', 0);downloads_categories` VALUES (4, 'Сканы', '', 3);downloads_categories` VALUES (5, 'Иконки и смайлики', '', 3);downloads_categories` VALUES (6, 'Анимация GIF', '', 3); И вторая таблица с самими файлами, где есть тоже CID (к какой категории файл относится). В таблице для котегорий, если PARENTID - это категория в которую входит подкатегория, если PARENTID=0, то соотв. она главная. Если мы смотрим подкатегорию, например Иконки и смайлики, то тут просто, делаем запрос в файлы и показываем все файлы CID которых = 5. Мне хочется сделать, чтобы если смотрим главную категорию, например Графика, то показывались все файлы, которые входят в ее подкатегории. Вот тут и запутался. Нужно если PARENTID=0, то зная CID нужно запросить все категории, PARENTID которых ровняется этому CID (на данном примере 4,5,6) а затем зная CID этих подкатегорий, запросить все файлы, которые соответсвуют им. Сказали что можно как то сделать через сложный запрос LEFT JOIN. У меня есть пример такого запроса, но там в другом применении немного. --- На всякий случай PHP 4, движок PHP-Nuke. Ссылка на комментарий Поделиться на другие сайты Поделиться
Shurr Опубликовано 22 июня, 2006 Жалоба Поделиться Опубликовано 22 июня, 2006 Зачем здесь left join... Если таблица с файлами выглядит так: CREATE TABLE `files` (`fid` int(11) NOT NULL auto_increment,`cid` varchar(50) NOT NULL default '',`file_name` varchar(255) NOT NULL,PRIMARY KEY (`fid`),KEY `cid` (`cid`)) То запрос select file_name from files f, downloads_categories dc where f.cid = dc.cid and dc.parentid=3 выберет все файлы, которые относятся к подразделам первого колена раздела с cid=3 (Графика) Ссылка на комментарий Поделиться на другие сайты Поделиться
Alexander-V-Sh Опубликовано 22 июня, 2006 Автор Жалоба Поделиться Опубликовано 22 июня, 2006 Shurr: Я такой запрос и невидел никогда. Но работает :( Сейчас буду мудрить с остальным :) Спасибо ГРОМАДНОЕ! :) Ссылка на комментарий Поделиться на другие сайты Поделиться
Alexander-V-Sh Опубликовано 22 июня, 2006 Автор Жалоба Поделиться Опубликовано 22 июня, 2006 Еще вот вопросик. Можно ли усложнить запрос, чтобы вытаскивая файлы еще отображались их категории. Было например так: --- Файл 1 Раздел: Графика. Подраздел: Иконки и смайлики. --- Файл 1 Раздел: Графика. Подраздел: Анимация GIF. --- Поля title совпадают в обеих таблицах, но соотв. разные, в категориях - название категории, в файла - название файла. Ссылка на комментарий Поделиться на другие сайты Поделиться
Shurr Опубликовано 22 июня, 2006 Жалоба Поделиться Опубликовано 22 июня, 2006 Поля title совпадают в обеих таблицах, но соотв. разные, в категориях - название категории, в файла - название файла. В смысле поле, которое я назвал `file_name` у тебя называется title? select f.title, f.cid, dc.title, dc.cdescription from files f, downloads_categories dc where f.cid = dc.cid and dc.parentid=3 Если ты обращаешься к результирующим полям по имени а не по порядковому номеру, и поэтому тебя смущает то, что два поля имеют одинаковое имя - им можно дать псевдонимы: select f.title as file_name, f.cid, dc.title as category_name, dc.cdescription from files f, downloads_categories dc where f.cid = dc.cid and dc.parentid=3 Я добавил в выборку cid, чтобы при необходимости можно было дать ссылку на категорию. Ссылка на комментарий Поделиться на другие сайты Поделиться
Alexander-V-Sh Опубликовано 22 июня, 2006 Автор Жалоба Поделиться Опубликовано 22 июня, 2006 Еще раз спасибо! С главной категорей все. С подкатегориями проще, но там 2 запроса получается. Нам известно изначально PARENTID (запрос идет в самом начале, чтобы узнать категория или подкатегория). Известен и CID Запрашиваем все файлы из подкатегории по CID и все. А чтобы узнать какая главная категория, нужно зная ее PARENTID запросить ее название. В такой же один запрос можно сделать? Чтобы запросить из таблицы для файлов все CID, а из таблицы для категорий запросить TITLE по PARENTID. Поидеи можно сделать и вручную категорий главных всего штук 5 будет, можно и условием сделать: IF CID=1 $cat = "Программы" Ссылка на комментарий Поделиться на другие сайты Поделиться
Ramzes_ Опубликовано 22 июня, 2006 Жалоба Поделиться Опубликовано 22 июня, 2006 (изменено) Насчет синтаксиса MySQL не знаю, но в Interbase делается так: SELECT f.title, cat.title, parent.title FROM files f JOIN downloads_categories cat ON cat.cid = f.cid JOIN downloads_categories parent ON parent.cid = cat.parentid WHERE cat.parentid=3 либо собрав все в кучу SELECT f.title, cat.title, parent.title FROM files f, downloads_categories cat, downloads_categories parent WHERE cat.cid = f.cid AND parent.cid = cat.parentid AND cat.parentid=3 Только нужно добавить корневой объект с cid=0 для запросов с категорией у которой parentid=0 Изменено 22 июня, 2006 пользователем Ramzes_ Ссылка на комментарий Поделиться на другие сайты Поделиться
Alexander-V-Sh Опубликовано 22 июня, 2006 Автор Жалоба Поделиться Опубликовано 22 июня, 2006 Ramzes_: С основным каталогом все получилось. Насколько я понял это запрос для него, хотя могу ошибаться... У меня такая последовательность: Когда заходишь в категорию, идет запрос в базу где проверяется PARENTID. Далее идет условие, если PARENTID=0, то это значит главная категория. Затем идет запрос, который сказал Shurr. Выводятся все файлы подкатегорий. Если PARENTID не равно 0, то там просто. Обычный запрос где CID файлов = CID подкатегории, в которой находишься. И файлы выводятся. К тому же PARENTID и заголовок подкатегории нам известно из первого запроса (до условия). Не хватает только одного, названия главной категории, PARENTID ее есть, но нет названия. 1 вариант - еще раз сделать запрос 2 вариант - прописать условие, чтобы название главной категории вынималось не из базы, а из кода. 3 вариант - незнаю. Это сразу вывести файлы и заодно узнать в категориях название. Ссылка на комментарий Поделиться на другие сайты Поделиться
Shurr Опубликовано 22 июня, 2006 Жалоба Поделиться Опубликовано 22 июня, 2006 Ну, во-первых, ты можешь сделать так, как показал Ramzes_. Во-вторых, все данные об основной категории ты можешь узнать еще в том запросе, в котором запрашиваешь ее PARENTID. Это позволит тебе избавиться от одного join'a. И независимо от того, как ты будешь это реализовывать - настойчиво нерекомендую зашивать что-то в код. Данные должны храниться в базе. Зашивание данных в код страницы - дурной тон, который может в будущем принести дополнительные неудобства. Ссылка на комментарий Поделиться на другие сайты Поделиться
Alexander-V-Sh Опубликовано 22 июня, 2006 Автор Жалоба Поделиться Опубликовано 22 июня, 2006 Shurr: все данные об основной категории ты можешь узнать еще в том запросе, в котором запрашиваешь ее PARENTID. А такой пример не приведешь? Сейчас у меня просто: SELECT title,parentid FROM downloads_categories WHERE cid='$cid' Ссылка на комментарий Поделиться на другие сайты Поделиться
Shurr Опубликовано 23 июня, 2006 Жалоба Поделиться Опубликовано 23 июня, 2006 У тебя же уже есть в выборке title. Вот и используй его. Если надо - добавь еще cdescription... SELECT title, parentid, cdescription FROM downloads_categories WHERE cid='$cid' P.S. Почитал бы ты какую-нибудь литературку по SQL... Дело не в том, что мне лень отвечать - это не сложно. Просто очень похоже, что с SQLем ты ознакомился исключительно по примерам, без теории. Тебе самому будет гораздо проще, если ты будешь знать возможности инструмента с которым работаешь. Ссылка на комментарий Поделиться на другие сайты Поделиться
Alexander-V-Sh Опубликовано 23 июня, 2006 Автор Жалоба Поделиться Опубликовано 23 июня, 2006 (изменено) Shurr: Эти данные я и так использую, но этот запрос выводит: (4, 'Сканы', '', 3); Имеем название подкатегории и PARINTID категории, а нужно еще название категории. (чтобы использовалась наверху странички и в самих файлах) (4, 'Сканы', '', 3) 3=Графика И получить: $podcateg = Сканы $parentid = 3 $categ = Графика -------------- Можно так: SELECT title, parentid FROM downloads_categories WHERE cid='$cid' SELECT title FROM downloads_categories WHERE cid='$parentid' Есть ли какая нибудь разница 2 запроса или в впихать 1 ? (с точки зрения нагрузки и т.д.) -------------- Литературу я еще не купил, а с компа читать не люблю, тут и так дела есть, а если еще и читать тут, то глаза на лоб вылезут. А вот почитать перед сном умные книги, это в планах есть, но книг пока нет... Ты прав, с PHP и MySQL я знаком только по примерам, смотрю как сделано в одном модуле и точно так же делаю в другом. Подгоняю методом научного втыка, пока не получится. А если сталкиваюсь с таким, когда примера нет, то и застрял как тут. Теперь вот имея примеры таких запросов, упрощу пару модулей, чтобы уменьшить запросы в БД или вывести подругому данные. Изменено 23 июня, 2006 пользователем Alexander-V-Sh Ссылка на комментарий Поделиться на другие сайты Поделиться
Shurr Опубликовано 23 июня, 2006 Жалоба Поделиться Опубликовано 23 июня, 2006 Alexander-V-Sh Что-то я совсем запутался. ;) Смотри, тебе приходит id категории. Ты делаешь запрос: SELECT title, parentid FROM downloads_categories WHERE cid='$cid' Допустим id категории равен 3, тогда результат такой: title = Графика, parentid = 0 Далее ты смотришь, если parentid=0, то: select f.title as file_name, f.cid, dc.title as category_name from files f, downloads_categories dc where f.cid = dc.cid and dc.parentid=3 Допустим ты имеешь такой результат: file_name = file1, cid = 4, category_name = Сканы file_name = file2, cid = 4, category_name = Сканы file_name = file3, cid = 5, category_name = Иконки и смайлики file_name = file4, cid = 5, category_name = Иконки и смайлики file_name = file5, cid = 6, category_name = Анимация GIF file_name = file6, cid = 6, category_name = Анимация GIF Имя раздела, Графика, ты узнал в первом запросе, оно общее для всех файлов, которые ты будешь выводить. Имя файла, cid подраздела и имя раздела у тебя есть в результате второго запроса. Чего тебе еще не хватает? Ссылка на комментарий Поделиться на другие сайты Поделиться
Alexander-V-Sh Опубликовано 23 июня, 2006 Автор Жалоба Поделиться Опубликовано 23 июня, 2006 (изменено) Shurr: Вот смотри ;) Человек заходит по сслыке, где CID равна 3,4,5 и т.д. Идет запрос в базу, где уточняется, раздел это или подраздел, заодно вынимаем title. После этого запроса получаем: $title $parentid Стоит условие, если parentid = 0, то это раздел и: SELECT d.lid, d.title as file_name, d.description, d.date, d.hits, d.totalcomments, d.filesize, d.version, d.homepage, dc.title as category_name, dc.cid as podcategory_name FROM ".$prefix."_downloads_downloads d, ".$prefix."_downloads_categories dc where d.cid = dc.cid and dc.parentid='$cid' order by $orderby limit $min,$perpage И выводим все файлы, которые входят во все подкатегории. А $title из первого запроса - стоит после слова Раздел: $title Это я сделал, за что большое спасибо. (как раз самое сложное) Если parentid не равно 0, то это подраздел и такой запросище делать нет необходимости. Там просто: SELECT lid, title, date, hits, totalcomments FROM ".$prefix."_downloads_downloads WHERE cid='$cid' order by $orderby limit $min,$perpage И выводим все файлы из подкатегории. А $title из первого запроса у нас уже как Подраздел : $title Но нет названия Раздела, в которую входит подраздел, есть только его parentid. --- Тут вот проще всего - это еще раз сделать запрос и вынуть title главной категории SELECT title FROM ".$prefix."_downloads_categories WHERE cid='$parentid' Отдельный вопрос: В этом случае получится 2 простых запроса (вынуть только 1 значение с базы). Стоит ли в таких случаях обьединять их сложным запросом (с целью оптимизации) или 2 запроса ничуть не хуже? Можно сделать кодом в данном случае. Категорий главных всего штук 5 и изменяться они врядли будут. Если $parentid=4, $name = Программы Если $parentid=6, $name = Графика Если $parentid=8, $name = Книги И все, никакого запроса в базу. А вот если разумнее всего в этом случае будет обьединить запросы в 1, или в первом (когда определяется parentid) или во 2, когда выводятся файлы. То вот тут и незнаю как. Если 2 простых ничуть не хуже 1 сложного, то я запрошу еще раз базу для заголовка главной категории и все ;) В код категории писать тоже не хочется. Изменено 23 июня, 2006 пользователем Alexander-V-Sh Ссылка на комментарий Поделиться на другие сайты Поделиться
Shurr Опубликовано 23 июня, 2006 Жалоба Поделиться Опубликовано 23 июня, 2006 ИМХО проще будет модифицировать первый запрос, чтобы он выбирал не только parentid, но и его title, если таковой имеется. SELECT dc.title, dc.parentid, dc.cdescription, pdc.title as parent_title FROM downloads_categories dc left join downloads_categories pdc on dc.parentid=pdc.cid WHERE dc.cid='$cid' Ссылка на комментарий Поделиться на другие сайты Поделиться
Alexander-V-Sh Опубликовано 23 июня, 2006 Автор Жалоба Поделиться Опубликовано 23 июня, 2006 Shurr: Вот теперь все. Спасиб Теперь сами файлы подредактирую аналогично, чтобы категории, подкатегории и сами файлы в 1 запрос уместить. И пример будет под рукой, если потребуется в других модулях применить. (а то некоторые циклются до 50-100 запросов в бд, когда можно в 1 уместить) Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти