Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: два запроса из одной таблицы с условием
 
 автор: aetern   (08.07.2009 в 23:35)   письмо автору
 
 

Делаю два запроса из одной таблицы с условием (код упрощен для примера):

    $query = "SELECT * FROM $tbl
              WHERE hide = 'show' AND col1 = 0";
    $sub = mysql_query($query);
        while($subcat = mysql_fetch_array($sub))
        {
        echo $subcat['name'];
              
        if($_GET['id_catalog'] == $subcat['id_catalog'])
            {
            $query2 = "SELECT * FROM $tbl
            WHERE hide = 'show' AND col2 = $_GET[id_catalog]";
            
            $sub2 = mysql_query($query2);
            while($subcat2 = mysql_fetch_array($sub2))
                {
                echo $subcat2['name'];
                } 
            }          
        }

Вопрос:
Как обьединить подобные действия в один запрос?
Я таким образом раскрываю меню товаров.
Если есть иные идеи подскажите. Спасибо.

  Ответить  
 
 автор: Trianon   (08.07.2009 в 23:52)   письмо автору
 
   для: aetern   (08.07.2009 в 23:35)
 

LEFT JOIN сам собой напрашивается.

  Ответить  
 
 автор: aetern   (08.07.2009 в 23:54)   письмо автору
 
   для: Trianon   (08.07.2009 в 23:52)
 

а разве LEFT JOIN не для двух разных таблиц?
Сейчас еще раз почитаю о нем...

  Ответить  
 
 автор: aetern   (09.07.2009 в 00:01)   письмо автору
 
   для: Trianon   (08.07.2009 в 23:52)
 

Пример из мануала:

SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key)
         WHERE b.key=d.key

попробую сделать a AS $tbl и b AS $tbl может чего получится...

  Ответить  
 
 автор: Trianon   (09.07.2009 в 00:03)   письмо автору
 
   для: aetern   (09.07.2009 в 00:01)
 

a, b тут явно лишнее

  Ответить  
 
 автор: Trianon   (09.07.2009 в 00:03)   письмо автору
 
   для: aetern   (09.07.2009 в 00:01)
 

слева и справа можно одну и ту же таблицу использовать с разными алиасами.

  Ответить  
 
 автор: aetern   (09.07.2009 в 10:18)   письмо автору
 
   для: Trianon   (09.07.2009 в 00:03)
 

У меня получилось что-то вроде:

$_GET['id'] = 1;
    $query = "SELECT a.*, b.* 
              FROM $tbl AS a
              INNER JOIN $tbl AS b
              ON b.col2 = $_GET[id] 
              WHERE a.hide = 'show' AND a.col1 = 0";
    $sub = mysql_query($query);
        while($subcat = mysql_fetch_array($sub))
        {
        echo $subcat['name'];
        echo '<br>';

Но результат является - дублирующее отображение ячейки "name" при прямом условии "b.col2 = $_GET[id] ".
Не могу сообразить как учитывать именно условие если есть переменная "$_GET['id']", а если нет, то условие не учитывать? .

  Ответить  
 
 автор: Trianon   (09.07.2009 в 11:08)   письмо автору
 
   для: aetern   (09.07.2009 в 10:18)
 

Во-первых SELECT a.name as a_name, b.name as b_name, ...

Во вторых, не INNER а LEFT OUTER JOIN

Ну и видимо не b.col2 = GET[id] а a.col2 = GET[id]

  Ответить  
 
 автор: aetern   (09.07.2009 в 11:59)   письмо автору
 
   для: Trianon   (09.07.2009 в 11:08)
 

Спасибо, виноват, был не внимателен.
Теперь все запрашивает отлично:

$_GET[id] = 1;
    $query = "SELECT a.id_catalog, a.col1, b.col2, a.hide, a.name AS a_name, b.name AS b_name
              FROM $tbl AS a
              LEFT JOIN $tbl AS b
              ON a.id_catalog = $_GET[id] AND b.col2 = $_GET[id]
              WHERE a.hide = 'show' AND a.col1 = 0";
    $sub = mysql_query($query);

while($subcat = mysql_fetch_array($sub))
        {
   echo '<b>'.$subcat['a_name'].'</b><br>';
   echo ''.$subcat['b_name'].'<br>';
        }


вот только с выводм результата не могу сообразить.
Как вывести "a_name", затем все ее "b_name", в соответствии с $_GET[id] . Не могу понять за что цепляться в массиве $subcat ?
И еще раз, спасибо за помощь.

  Ответить  
 
 автор: Trianon   (09.07.2009 в 14:24)   письмо автору
 
   для: aetern   (09.07.2009 в 11:59)
 

Это уже с БД никак не связано. Это обычная логика алгоритма.
Если при предыдущем значении имени часть кода требуется опустить, нужно так и записать.
В виде условного оператора.
$aname = '';
while($subcat = mysql_fetch_array($sub))
{
  if($aname != $subcat['a_name']) 
  {
    $aname = $subcat['a_name'];
    echo '<b>'.$aname.'</b><br>';
  }
  echo ''.$subcat['b_name'].'<br>';
}


Откуда берется поток данных - из массива, из таблицы, из файла или еще откуда - совершенно неважно.

  Ответить  
 
 автор: aetern   (09.07.2009 в 14:56)   письмо автору
 
   для: Trianon   (09.07.2009 в 14:24)
 

Спасибо. Я примерно так и поступил, тока не успел отписать.
Все-таки оптимизация запросов - это здорово, чувствуешь себя человеком.

  Ответить  
 
 автор: aetern   (09.07.2009 в 20:13)   письмо автору
 
   для: aetern   (09.07.2009 в 11:59)
 

При оптимизации столкнулся еще с одной трудностью - сортировка.
в коде, где условие постоянное:
$_GET[id] = 1; 
    $query = "SELECT a.name AS a_name, b.name AS b_name 
              FROM $tbl AS a 
              LEFT JOIN $tbl AS b 
              ON a.id_catalog = $_GET[id] AND b.col2 = $_GET[id] 
              WHERE a.hide = 'show' AND a.col1 = 0
              ORDER BY a.pos, b.pos DESC";

все работает, но если сделать условие переменное:
$query = "SELECT a.name AS a_name, b.name AS b_name 
              FROM $tbl AS a 
              LEFT JOIN $tbl AS b 
              ON a.id_catalog = b.col2
              WHERE a.hide = 'show' AND a.col1 = 0
              ORDER BY a.pos, b.pos DESC";


то "ORDER BY a.pos, b.pos DESC" - творит чудеса.

В чем сдесь проблема?

  Ответить  
 
 автор: Trianon   (09.07.2009 в 20:34)   письмо автору
 
   для: aetern   (09.07.2009 в 20:13)
 

Второй вообще никак не зависит от GET
Разные запросы выдают разные данные.
Что Вас удивляет?

  Ответить  
 
 автор: aetern   (09.07.2009 в 20:43)   письмо автору
 
   для: Trianon   (09.07.2009 в 20:34)
 

Видимо я не правильно понимаю логику LEFT JOIN и ORDER во втором примере.
Мне необходимо произвести сортироку в указанной таблице по возрастанию по столбцу "pos", где соответственно a.pos имеет значения 1,2,3,4 и т.д. и аналогично сформирован столбик b.pos 1,2,3,4
Конечная цель - раскрыть все разделы меню.

  Ответить  
 
 автор: GeorgeIV   (09.07.2009 в 20:51)   письмо автору
 
   для: aetern   (09.07.2009 в 20:13)
 

Сравнивать два поля с переменной, это не то же самое, что сравнивать их между собой

  Ответить  
 
 автор: aetern   (09.07.2009 в 20:58)   письмо автору
 
   для: GeorgeIV   (09.07.2009 в 20:51)
 

Я это отлично понимаю. Но я не могу понять как отсортировать результат при подобном сравнении.

  Ответить  
 
 автор: aetern   (09.07.2009 в 21:40)   письмо автору
 
   для: aetern   (09.07.2009 в 20:13)
 

Неужели никто даже не намекнет как отсортировать по a.pos и b.pos?
Может есть какие-то операторы? Или надо менять весь подход?

  Ответить  
 
 автор: Trianon   (09.07.2009 в 21:58)   письмо автору
 
   для: aetern   (09.07.2009 в 21:40)
 

Вы бы привели фрагмент дампа таблицы, а заодно и результат, который получаете, и который ожидаете получить.
А то так Вас не понять.
Вы под чудесами имеете в виду одно. SQL - другое.
(Я - третье)

  Ответить  
 
 автор: aetern   (09.07.2009 в 22:13)   письмо автору
 
   для: Trianon   (09.07.2009 в 21:58)
 

Дамп:

--
-- Структура таблицы `goods`
--

CREATE TABLE IF NOT EXISTS `goods` (
  `id_catalog` int(11) NOT NULL auto_increment,
  `name` tinytext NOT NULL,
  `description` text NOT NULL,
  `pos` int(11) NOT NULL default '0',
  `hide` enum('show','hide') NOT NULL default 'show',
  `id_parent` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id_catalog`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=9 ;

--
-- Дамп данных таблицы `goods`
--

INSERT INTO `goods` (`id_catalog`, `name`, `description`, `pos`, `hide`, `id_parent`) VALUES
(1, 'Детская мебель', 'Раздел с детскими колясками', 1, 'show', 0),
(2, '2 - Детские кроватки 1', '', 2, 'show', 1),
(3, '1 - Комод пеленальный 2', '', 1, 'show', 1),
(4, '3 - Комод бельевой 3', '', 3, 'show', 1),
(5, 'Автокресла', '', 1, 'show', 0),
(6, 'Автокресло - переноска категория 0/0+', '', 1, 'show', 5),
(7, 'Автокресло категории 0+/1', '', 2, 'show', 5),
(8, 'Автокресло категории 0/ 1/2', '', 3, 'show', 5);



Запрос:

    
    $query = "SELECT a.id_catalog AS a_catalog, b.id_catalog AS b_catalog, b.id_parent AS b_parent, a.name AS a_name, b.name AS b_name
              FROM $tbl_menu_goods AS a 
              LEFT JOIN $tbl_menu_goods AS b
              ON b.hide = 'show' AND b.id_parent = a.id_catalog 
              WHERE a.hide = 'show' AND a.id_parent = 0
              ORDER BY a.pos, b.pos ASC"; // Здесь камень предкновения


Вывод результата:


$aname = ''; 
        while($result = mysql_fetch_array($sub)) 
        { 
         if($aname != $result['a_name'])  
            { 
            $aname = $result['a_name']; 
        echo "<h4><a href=\"".$root."/goods.php?id_catalog=".$result['a_catalog']."&parent=0\" 
                     class=\"menu_lnk\">".$result['a_name']."</a>
              </h4>";
             } 
        echo "<a href=\"".$root."/goods.php?id_catalog=".$result['b_catalog']."&parent=".$result['b_parent']."\" 
                     class=\"menu_lnk\">".$result['b_name']."</a>
              <br>";    
        }


Хочу получить:

Детская мебель
1 - Комод пеленальный 2
2- Детские кроватки 1
3 - Комод бельевой 3
Автокресла
Автокресло - переноска категория 0/0+
Автокресло категории 0+/1
Автокресло категории 0/ 1/2

  Ответить  
 
 автор: aetern   (09.07.2009 в 22:16)   письмо автору
 
   для: Trianon   (09.07.2009 в 21:58)
 

При ORDER BY a.pos, b.pos ASC получаю:

Детская мебель
1 - Комод пеленальный 2
Автокресла
Автокресло - переноска категория 0/0+
Детская мебель
2 - Детские кроватки 1
Автокресла
Автокресло категории 0+/1
Детская мебель
3 - Комод бельевой 3
Автокресла
Автокресло категории 0/ 1/2

При ORDER BY a.pos ASC";
Выходит:
Детская мебель
2 - Детские кроватки 1
1 - Комод пеленальный 2
3 - Комод бельевой 3
Автокресла
Автокресло - переноска категория 0/0+
Автокресло категории 0+/1
Автокресло категории 0/ 1/2

  Ответить  
 
 автор: Trianon   (09.07.2009 в 23:14)   письмо автору
 
   для: aetern   (09.07.2009 в 22:16)
 

У Вас a.pos неоднозначны.
ORDER BY a.pos ASC , a.id_catalog ASC , b.pos ASC

  Ответить  
 
 автор: aetern   (09.07.2009 в 23:19)   письмо автору
 
   для: Trianon   (09.07.2009 в 23:14)
 

Гениально!
Спасибо.
Жаль, что сам к этому не пришел? :-(

  Ответить  
 
 автор: Trianon   (09.07.2009 в 23:26)   письмо автору
 
   для: aetern   (09.07.2009 в 23:19)
 

>Жаль, что сам к этому не пришел? :-(

Вам никто не мешал. Если не сказать более жестко.

  Ответить  
 
 автор: Valick   (10.07.2009 в 01:21)   письмо автору
 
   для: Trianon   (09.07.2009 в 23:26)
 

более жестко
сегодня зашёл к другу у которого не был около трёх лет, пили много пива, говорили... и хотя проблем не поубавилось, но на жизнь стал смотреть чуточку оптимистичнее.... может ну его этот форум нервотрёпку айда по гостям?) Я реально понимаю зависимость от этого форума, я благодарен людям которые нашли время и силы "заварить эту кашу" - теперь это часть моей жизни, но сколько волка не корми всё равно у медведя шкура толще.....
"Давайте делать паузы в словах,
Произнося и умолкая снова,
Чтоб лучше отдавалось в головах
Значенье вышесказанного слова.
Давайте делать паузы в словах.

Давайте делать паузы в пути,
Смотреть вокруг внимательно и строго,
Чтобы случайно дважды не пройти
Одной и той неверною дорогой.
Давайте делать паузы в пути."
заранее приношу извинения за вышесказанное, но именно таким я чувствую мир в данный момент времени. С уважением Валерий.

  Ответить  
 
 автор: Trianon   (10.07.2009 в 01:32)   письмо автору
 
   для: Valick   (10.07.2009 в 01:21)
 

Хорошо....

  Ответить  
 
 автор: GeorgeIV   (09.07.2009 в 11:11)   письмо автору
 
   для: aetern   (09.07.2009 в 10:18)
 

.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования