За последние 24 часа нас посетили 48254 программиста и 1807 роботов. Сейчас ищет 1561 программист ...

Цикл в цикле

Тема в разделе "PHP для новичков", создана пользователем McLotos, 10 июн 2011.

  1. McLotos

    McLotos Активный пользователь

    С нами с:
    24 фев 2011
    Сообщения:
    90
    Симпатии:
    0
    Подскажите как реализовать, а то я что-то запутался.
    У меня 2 запроса к БД
    1. Вытягивает все Distinct recipient из таблицы Calls
    2. По найденным recipient вытягивает все остальные данные из той же таблицы.
    Подскажите примерно как должна выглядеть такая конструкция?
     
  2. engager

    engager Активный пользователь

    С нами с:
    21 янв 2009
    Сообщения:
    1.106
    Симпатии:
    1
    на 99,9% уверен, что можно решить задачу путем модификации SQL-запроса.
    нужно использовать join'ы, тогда можно будет сделать все за один проход.

    пиши подробнее. структуру таблицы, какую логику нужно реализовать.
     
  3. McLotos

    McLotos Активный пользователь

    С нами с:
    24 фев 2011
    Сообщения:
    90
    Симпатии:
    0
    Ну структура таблицы [sql]
    CREATE TABLE IF NOT EXISTS `Calls` (
    `id_call` int(100) NOT NULL AUTO_INCREMENT,
    `personal` enum('0','1') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
    `contract` varchar(11) NOT NULL,
    `group` varchar(11) NOT NULL,
    `phone_number` varchar(11) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
    `date_of_call` date DEFAULT NULL,
    `time_of_call` text,
    `duration` text,
    `rounded_duration` text NOT NULL,
    `cost` float DEFAULT NULL,
    `outgoing` varchar(11) NOT NULL,
    `recipient` varchar(16) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
    `type_of_call` text NOT NULL,
    `description` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
    `connection_type` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
    `station_number` varchar(11) NOT NULL,
    `volume` float DEFAULT NULL,
    `roaming` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
    PRIMARY KEY (`id_call`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=73746 ;[/sql]
    А если более детально то такая схема нужна специально, потому-что после первого запроса строится список, после второго запроса список заполняется таблицами. Т.е. список имеет вид
    recipient1
    recipient2
    recipient3
    и т.д.
    при клике на recipient1 из него выпадают все данные связанные с этим номером, которые имеются в таблице. В результате имеем 2 запроса 1 [sql]SELECT distinct recipient FROM Calls WHERE phone_number=$phone_number and Calls.Cost>0 order by recipient[/sql]
    и второй [sql]SELECT * FROM Calls WHERE phone_number=$phone_number and recipient=$show[recipient] and Calls.Cost>0 order by date_of_call[/sql]
    Только есть ещё 1 момент, не пойму почему фторой запрос не видит $show['recipient'], пробовал вместо него ставить переменную, бесполезно. Ну хотя суть вопроса пока не в этом. Для начала нужно понять как сделать чтобы вся конструкция работала так как нужно.
    для наглядности, вот линка http://www.jankoatwarpspeed.com/post/2009/07/20/Expand-table-rows-with-jQuery-jExpand-plugin.aspx Примерно так, только внутри не список а таблица
     
  4. engager

    engager Активный пользователь

    С нами с:
    21 янв 2009
    Сообщения:
    1.106
    Симпатии:
    1
    значит так.
    делаем селект один(!)
    [sql]SELECT
    *
    FROM
    Calls
    WHERE
    phone_number=$phone_number and Calls.Cost>0
    order by
    recipient[/sql]

    Далее делаем один(!) цикл
    PHP:
    1.    $rec = '';
    2.    while ($row = mysql_fetch_assoc($res)) {
    3.      if ($row['recipient'] != $rec) {
    4.        if ($rec != '') echo ("</table>");
    5.        $rec = $row['recipient'];
    6.        echo ("<div>".$rec." recipents calls:</div><table><tr>Phone number<td>Duration</td></tr>"); // тут столбцы по необходимости добавишь
    7.      }
    8.      echo('<tr><td>'.$row['phone_number'].'</td><td>'.$row['duration'].'</td></tr>');
    9.    }
    10.    if ($rec != '') echo ("</table>");
    Если ты пойдешь своим путем - ... короче, не делай этого, у тебя будет миллион лишних обращений к базе и потеря в производительности. Приучайся сразу делать все правильно, учись искать пути оптимизации прямо на этапе проектирования.
     
  5. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Как формируется итоговая таблица? Сразу вся? Или по нажатию информация подгружается AJAX'ом?

    Но незабываем о вреде преждевременной оптимизации. =))
     
  6. engager

    engager Активный пользователь

    С нами с:
    21 янв 2009
    Сообщения:
    1.106
    Симпатии:
    1
    судя по той ссылке, которую он дал, там аякса нет, весь стафф генериться один раз, а все красивости уже на клиенте жава-скриптом
     
  7. McLotos

    McLotos Активный пользователь

    С нами с:
    24 фев 2011
    Сообщения:
    90
    Симпатии:
    0
    Вот полный код, чтобы было понятнее о чем я говорю. А что должно получиться в итоге (см.ссылку в предыдущем посте)
    PHP:
    1.  
    2.  $recipients="SELECT distinct recipient FROM Calls WHERE phone_number=$phone_number  AND Calls.date_of_call
    3. BETWEEN DATE_SUB(DATE_SUB(CURDATE(), INTERVAL 1 MONTH), INTERVAL DAY(CURDATE())-1 DAY)
    4. AND DATE_SUB(CURDATE(), INTERVAL DAY(CURDATE()) DAY) and Calls.Cost>0 order by recipient";
    5.  $find=mysql_query($recipients);
    6.  $show=mysql_fetch_array($find);
    7.  $phone=$show['recipient'];
    8. if($find)
    9.  { $query="SELECT * FROM Calls WHERE phone_number=$phone_number  AND Calls.date_of_call
    10. BETWEEN DATE_SUB(DATE_SUB(CURDATE(), INTERVAL 1 MONTH), INTERVAL DAY(CURDATE())-1 DAY)
    11. AND DATE_SUB(CURDATE(), INTERVAL DAY(CURDATE()) DAY) and recipient=$phone and Calls.Cost>0 order by date_of_call";
    12. $result=mysql_query($query);
    13. $myrow=mysql_fetch_array($result);
    14. echo $myrow['phone_number'];
    15.        $o=array($tcalls);
    16.        $o[]="<form method=\"post\" action=\"page.php\" >";
    17.        $total=0;
    18.        $total_personal=0;
    19.        $total_rouming=0;
    20.        $id=0;
    21.        $month=date('M');
    22.        $day=date('d');
    23.        while($show = mysql_fetch_array($find))
    24.        {if($id==0)
    25.              {   $id=1;
    26.                  $a=explode('-',$myrow['date_of_call']);
    27.                  $month=$a[0];
    28.                  $day=$a[1];
    29.              }
    30.              $value=$myrow['phone_number'].'@'.$myrow['date_of_call'].'@'.$myrow['time_of_call'];
    31.              if($myrow['cost']!='' and $myrow['cost']!=null)
    32.              {    if($myrow['personal']==1)
    33.                   {$total_personal+=$show['cost'];}
    34.                   if($myrow['rouming']!=' ' and $myrow['rouming']!=null )
    35.                   {$total_rouming+=$myrow['cost'];}
    36.                   $total+=$myrow['cost'];
    37.                   if ($total_personal>500)
    38.                   {$stat_VAT=$total_personal*$VAT;}
    39.                   if ($stat_VAT!='' and $stat_VAT!=null)
    40.                   {$stat_total_with_VAT=$stat_VAT+$total_personal;}
    41.              }
    42.              if($myrow['personal']==1)
    43. {$o[]="<td class='check'><input type=checkbox name='call_select[]' checked data-on='Personal' data-off='Business' value='$value' ></td>";}
    44.              else
    45. {$o[]="<td class='check'><input type=checkbox name='call_select[]' data-on='Personal' data-off='Business'  value='$value' ></td>";}
    46.  $o[]="<td></td><td>{$show['recipient']}</td><td><div class='arrow'></div></td>"; //вытягиваем номер телефона для шапки
    47.  $o[]="<td>{$myrow['cost']}</td>"; //стоимость звонка на этот номер
    48.  $o[]="<td>{$myrow['recipient']}</td>"; //указываем на какой номер (просто чтобы увидеть что данные тянутся правильно)
    49.  $o[]="<td>{$myrow['date_of_call']}</td>"; //дата звонка
    50.  $o[]="<td>{$myrow['time_of_call']}</td>"; //время звонка
    51.  $o[]="<td>{$myrow['duration']}</td>"; //длительность
    52.  $o[]="<td>{$myrow['type_of_connect']}</td>"; //тип соединение
    53.  $o[]="<td>{$myrow['volume']}</td>"; //объём
    54.  $o[]="<td>{$myrow['roaming']}</td>"; //роуминг
    55.  $o[]="</td></tr>";
    56.  //только всю информацию по звонкам нужно вытягивать через другой цикл, потому-что на один и тот же номер может быть несколько звонков
    57.  }
    58.        $o[]="</table>";
    59.        $o[]="<input type='submit' name='set_personal' value='RESULT'>";
    60.        $o[]="</form><br>";
    61.  
     
  8. McLotos

    McLotos Активный пользователь

    С нами с:
    24 фев 2011
    Сообщения:
    90
    Симпатии:
    0
    А в предложенном варианте что такое $rec=' '
     
  9. engager

    engager Активный пользователь

    С нами с:
    21 янв 2009
    Сообщения:
    1.106
    Симпатии:
    1
    Просто переменная. C помощью нее производится отслеживание того, что в результирующем множестве пошли данные по новому ресипиенту. В таком случае закрывается предыдущая таблица и открывается новая.