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

Форум MySQL

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

 

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

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

тема: Обьединение и вывод информации из двух полей с чередованием строк
 
 автор: Axxil   (16.08.2005 в 17:28)   письмо автору
 
 

(не знаю как описать тему. Можно поправить :))
Задача.

Есть в базе два поля типа текст.

Первое с вопросами клиента questions вида:

[add 2005-08-16 16:01:02] question 1
[add 2005-08-16 16:10:15] question 2

Второе с ответами answers вида:

[add 2005-08-16 16:02:02] answer to question 1
[add 2005-08-16 16:14:15] answer to question 2

Задача объединить эти два поля и вывести в виде вопрос-ответ

Как это лучше сделать? В базе с помощью регулярных выражений, в скрипте с помощью их же или как-то иначе?

Спасибо.

   
 
 автор: cheops   (16.08.2005 в 17:35)   письмо автору
 
   для: Axxil   (16.08.2005 в 17:28)
 

А нельзя нормализовать данные, т.е. строку [add 2005-08-16 16:01:02] выделить в отдельное поле с уникальным индексом, а question 1 и answer to question 1 сопоставить эти индексы?

   
 
 автор: Axxil   (16.08.2005 в 17:46)   письмо автору
 
   для: cheops   (16.08.2005 в 17:35)
 

А можно это на лету сделать? То есть это поле создать динамически. Просто я разбираю уже довольно большой архив оформленный таким образом.
С нуля я бы так и сделал :)

   
 
 автор: cheops   (16.08.2005 в 17:55)   письмо автору
 
   для: Axxil   (16.08.2005 в 17:46)
 

А ну если уже заполненый большой архив - тогда нет вопросов - нужно работать с тем, что есть, а не перекраивать, чтобы не было ещё хуже... :))) А поля находятся в одной таблице или разных? Попробуйте следующий финт:
SELECT SUBSTRING(quest,25) AS quest,
                  SUBSTRING(answer,25) AS answer 
                  SUBSTRING(quest,1,25) AS putdate 
FROM tbl 
GROUP BY putdate

   
 
 автор: Axxil   (16.08.2005 в 18:11)   письмо автору
 
   для: cheops   (16.08.2005 в 17:55)
 

Так я только вытащу первую дату ответа, и всё что после первых дат в полях вопроса и ответа.

а мне надо вытащить в формате
[дата вопроса 1] Текст вопроса
[дата ответа 1] Текст ответа
[дата вопроса 2] Текст вопроса
[дата вопроса 3] Текст вопроса
[дата ответа 2] Текст ответа

То есть между двумя ответами может быть несколько вопросов.

   
 
 автор: cheops   (16.08.2005 в 20:05)   письмо автору
 
   для: Axxil   (16.08.2005 в 18:11)
 

Хм... а почему только первую? Вроде должно тащиться любая уникальная дата?
А что это вообще за система? На один вопрос может быть только один ответ (FAQ) или несколько (Обсуждение)?

   
 
 автор: Axxil   (17.08.2005 в 09:59)   письмо автору
 
   для: cheops   (16.08.2005 в 20:05)
 

Это система помощи. Клиент может задать вопрос, потом его уточнить в рамках этого вопроса и.тд. Поэтому и получается так. На самом деле один вопрос - один ответ, но с этими уточнениями.. Ещё раз повторюсь не я это писал, приходится работать с тем что есть :-(

Не работает. Непонятно, что такое quest, answer. Если поля вопрроса и ответа, тогда
так и получается как я написал выше. Вытаскивается подстрока начиная с 26 символа. а дата с 1 по 25. Или я не прав?

Я вот думал, даты ведь выглядят одинаково. Поэтому можно же наверное вытащить значение между [add и ] обозначив как дату, и после ] до [ обозначив как текст. Вот только как?

   
 
 автор: cheops   (17.08.2005 в 13:07)   письмо автору
 
   для: Axxil   (17.08.2005 в 09:59)
 

А какже тогда различать уточняющие ответы которые следуют позже? Они же могут за второй день перелезть или перемешаться с другими ответами - как узнать принадлежность к вопросу? В старой системе никаких наводок нет?

   
 
 автор: Axxil   (17.08.2005 в 13:45)   письмо автору
 
   для: cheops   (17.08.2005 в 13:07)
 

Принадлежность к вопросу определется просто один вопрос - одна запись в таблице. А уже в полях этой записи question и answer происходит накопление уточняющих вопросов и ответов. Чаще всего да, один вопрос - один ответ. Нобывает и целая дискуссия по вопросу . Т.о. все вопросы по времени старше последнего ответа но младше следующего адресуются именно следующему ответу.
Представьте себе тему форума. Так вот первый пост темы это главный вопрос, а все остальные это уточняющие вопросы и ответы. Только у меня это всё в рамках двух полей типа текст одной записи (типа темы форума в этой аналогии)

   
 
 автор: cheops   (17.08.2005 в 19:18)   письмо автору
 
   для: Axxil   (17.08.2005 в 13:45)
 

А понятно, я без структуры таблицы перед глазами не сообразил, что оба поля в одной таблице, тогда можно попытаться решить пробему следующим образом
SELECT quest, answer
FROM tbl 
ORDER BY quest DESC, answer DESC

А в цикле вывода - следить когда поле quest меняется - значит пошёл другой вопрос. К сожалению, плохая организация базы потребует большей работы в прикладном коде.

   
 
 автор: axxil   (17.08.2005 в 19:44)   письмо автору
 
   для: cheops   (17.08.2005 в 19:18)
 

Так в этом и вопрос как ВНУТРИ поля разобрать записи.
Они ВНУТРИ поля одной строки имеют вид
[add ... ] text
[add ... ] text

выполняя ваш запрос я получу

<?
  $ret
=array();
  
whyle ($r=mysql_fetch_assoc($query)){
    
array_push($ret,$r);
  }
//Теперь возьмём например  1 строку полученного массива
  
echo $ret[0]['quest'];
  echo 
"<br>";
  echo 
$ret[0]['answer']
// Получаем вывод:
// [add дата1] quest text1 [add дата2] quset text2
// [add дата1] answer text1 [add дата2] answer text2
?>


Хорошо :)

Пусть будет просто файл организованый как показано выше
как преобразовать его в массив чтобы в первой колонке была дата а во второй текст вопроса? С помощью регулярного выражения наверное?

   
 
 автор: cheops   (18.08.2005 в 02:34)   письмо автору
 
   для: axxil   (17.08.2005 в 19:44)
 

Хм... а почему бы поле просто не распотрошить substr
<?php
[add 2005-08-16 16:01:02question 1
  $key 
substr($ret[0]['quest'], 5,20);
  
$val substr($ret[0]['quest'], 25);
  
$arr[$key] = $val;
?>

   
 
 автор: Axxil   (18.08.2005 в 10:39)   письмо автору
 
   для: cheops   (18.08.2005 в 02:34)
 

Это можно сделать для первой даты, а как определить позицию следующей?

[add 2005-08-16 16:01:02] question with not many words [add 2005-08-17 11:01:02] question with unknown num of words. And how i can find position of previous datе?

я ведь не знаю сколько будет символов в вопросе. Мне кажется тут только регулярным выражением можно решить. А вот в них я не силён :-(

   
 
 автор: cheops   (18.08.2005 в 13:39)   письмо автору
 
   для: Axxil   (18.08.2005 в 10:39)
 

Стоп. Так они ещё и не в разных записях, а навалены в одну кучу? Ммм... не могли бы вы мне кусочек таблицы привести, чтобы я понял с чем мы имеем дело. Если не хотите здесь выкладывать пришлите по почте.

   
 
 автор: Axxil   (18.08.2005 в 15:10)   письмо автору
 
   для: cheops   (18.08.2005 в 13:39)
 

К сожалению я не могу привести реальные данные из таблицы, так там присутствует финансовая информация. Но я создал 2 тестовые строчки которые отражают общую картину. Прикладываю экспортный файл из EMS MySQL Manager.
Надеюсь так понятнее будет.
PS там в поле bofy идут теги оформления, не обращайте внимание это временно...

   
 
 автор: cheops   (18.08.2005 в 22:52)   письмо автору
 
   для: Axxil   (18.08.2005 в 15:10)
 

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

   
 
 автор: Axxil   (19.08.2005 в 09:43)   письмо автору
 
   для: cheops   (18.08.2005 в 22:52)
 

Мне кажется мы всё черезмерно усложняем :)
Задача стоит всего навсего разобрать два поля в строке: body и answer_body,
не рассматривая остальные строки. То есть надо из этих полей получить два массива body = array('date','question') и answer = array('date','answer'). То есть это уже не касается базы, это целиком работа с текстом.

   
 
 автор: cheops   (19.08.2005 в 13:13)   письмо автору
 
   для: Axxil   (19.08.2005 в 09:43)
 

Хм... тогда не понимаю, почему не подходит
<?php 
  $key 
substr($ret[0]['quest'], 5,20); 
  
$val substr($ret[0]['quest'], 25); 
  
$arr[$key] = $val
?>

Ведь этот код вроде эту задачу и решает, при условии, что все ответы и вопросы находятся в разных полях?

   
 
 автор: Axxil   (19.08.2005 в 14:37)   письмо автору
 
   для: cheops   (19.08.2005 в 13:13)
 

\* бьётся в истерике \* Почему меня не понимают???

<?php
  $str
='[add 2005-08-19 12:23:45]
          This is first question to support. Please help me.
        [add 2005-08-19 16:21:54]
          Hello... Where are you? Why my question isn\'t answered yet?
        [add 2005-08-19 19:10:54]
          Haliluja! Thanks for your answer!'
;

  
$key substr($str5,19);
  
$val substr($str25);
  
$arr[$key] = $val;
  echo 
"<pre>";
  
print_r($arr);
  echo 
"</pre>";
?>

вывод:

Array
(
    [2005-08-19 12:23:45] => 
          This is first question to support. Please help me.
        [add 2005-08-19 16:21:54]
          Hello... Where are you? Why my question isn't answered yet?
        [add 2005-08-19 19:10:54]
          Haliluja! Thanks for your answer!
)

Видите, мы получаем один(!) ключ. а все остальные даты попалают в значение.
А надо чтобы все (!) даты стали ключами

   
 
 автор: cheops   (19.08.2005 в 22:46)   письмо автору
 
   для: Axxil   (19.08.2005 в 14:37)
 

А.... :))) А я подумал, что ответы и вопросы в разных полях и для каждого ответа выделена отдельная запись... Тогда действительно всё можно просто разбить при помощи регулярных выражений
<?php
  $str
='[add 2005-08-19 12:23:45] 
          This is first question to support. Please help me. 
        [add 2005-08-19 16:21:54] 
          Hello... Where are you? Why my question isn\'t answered yet? 
        [add 2005-08-19 19:10:54] 
          Haliluja! Thanks for your answer!'
;
  
preg_match("|\[add ([^\]]*)\]([^\[]+)|i",$str,$out);
  
print_r($out);
?>

   
 
 автор: Axxil   (20.08.2005 в 10:18)   письмо автору
 
   для: cheops   (19.08.2005 в 22:46)
 

Ну наконец-то мы друг друга поняли !!! :)

Ну а теперь выражение не правильно работает вот вывод:

Array
(
    [0] => [add 2005-08-19 12:23:45]
          This is first question to support. Please help me.
        
    [1] => 2005-08-19 12:23:45
    [2] => 
          This is first question to support. Please help me.
        
)


Первый вопрос нормально записался, а как же остальные?

   
 
 автор: Axxil   (20.08.2005 в 11:03)   письмо автору
 
   для: Axxil   (20.08.2005 в 10:18)
 

Всё понял, дедуктивным методом :)

preg_match_all

спасибо огромное за терпение и помощь.

   
Rambler's Top100
вверх

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