Отображение данных одной таблицы на основе идентификатора другой с использованием SQL, PHP (стиль RSS) - PullRequest
0 голосов
/ 17 октября 2011

, вероятно, просто для тренированного глаза, но я слишком долго мучился из-за этого ..

У меня есть две таблицы базы данных, предназначенные для создания RSS-каналов в браузере: «Канал» и «Элемент»:


**Channel Table**  Primary Key: Id
Id   Title       Desc         Link
1    News        latest       www...
2    Sport       latest       www...
3    Gossip      latest       www..

Как вы можете видеть, существует более одного канала, который занимает центральное место в моем запросе.

**Item Table** Primary Key: Id, Index Key: Chan_Id
Id   Title       Desc         Link   Chan_Id
1    Footie      Liv-ManU1    www...    2
2    Cricket     India-Eng..  www...    2
3    G5 Summit   G5 Talks..   www...    1
4    X-Factor    Simon Cowell.www...    3
5    Iraq        MOD says...  www...    1
6    M Jackson   Court trial..www...    3

Теперь я видел сценарии, где RSS-канал может отображаться через PHP, и он прекрасно работает - основная проблема - все примеры, которые я видел, предполагает, что у вас есть только один канал для прикрепления ваших элементов к ..

News

G5 Summit   G5 Talks......  
Iraq        MOD says......  

, поскольку у меня более одного канала, мне нужно сначала распечатать несколько каналов с соответствующим контентом:

News
G5 Summit   G5 Talks......  
Iraq        MOD says......  

Sport
Footie      Liv-ManU1.....  
Cricket     India-Eng.....  

Gossip
X-Factor    Simon Cowell..  
M Jackson   Court trial..   

затем в конечном итоге вывести эти данные в отдельные xml-файлы, в зависимости от предмета (Footie.xml, Cricket.xml и т. Д.). Эта часть просто нуждается в небольшой подстройке, так как у меня есть формула для этого с использованием PHP DOM для построения и сохраните:

$doc->save(row['chan_title']) 

не точный синтаксис, но метод, который я использую, работает, но показывает только каналы, а НЕ элементы. Центральный вопрос в два раза:

  1. SQL-запрос: как мне выбрать данные из БД в качестве объединения? Если это так, то Inner Join похож на это:

    ВЫБРАТЬ Channel.Id, Channel.Title, Item.Title, Item.Desc, Item.Chan_Id С канала ВНУТРЕННЕЕ СОЕДИНЕНИЕ ON Channel.Id = Item.Chan_Id ORDER BY Channel.Id

или, может быть, использовать подзапрос?

  1. Как мне тогда получить данные из двух таблиц и отобразить их с помощью PHP? Было бы легче обернуть методы в классах и сделать это таким образом? Я пытался использовать while( channel query) внутри while( item query) внутри foreach( item), но отображал только информацию о канале. Возможно, неправильная перестановка, но я экспериментировал с целью найти решение, но мне нужна помощь специалиста, чтобы я мог двигаться дальше !!

Буду признателен за вашу помощь, я постараюсь ответить, как только смогу.

РЕДАКТИРОВАТЬ - Ничего себе, 2 дня и без ответа, не может быть так сложно !! Ну, на самом деле это не так. Мне не нужно, чтобы это было так сложно, главное было больше о правильном синтаксисе. Все еще не нашел правильного решения, но приблизился - я решил использовать два запроса с двумя while операторами, один внутри другого:

$detQry = sprintf("SELECT * FROM ".$detailsTable);
$itQry = sprintf("SELECT id, title, description FROM ".$itemsTable." WHERE chan_id = ".$detailsTable.".id ORDER BY chan_id ASC LIMIT 0, 30 ");
$result = mysql_query($detQry) OR die ('Could not execute query: ' . mysql_error());
$run = mysql_query($itQry) OR die ('Could not execute query: ' . mysql_error());

while($row = mysql_fetch_assoc($result)) {
echo $row['title'].'<br>';
echo $row['description'].'<br><br>';

while(list($ttl, $dsc, $pbd) = mysql_fetch_array($run)) {
    echo $ttl.'<br>';
    echo $dsc.'<br><br>';
    echo $pbd.'<br><br><br>';
}
}

Проблема в том, что когда я запускаю этот скрипт, печатаются только заголовки и описания Канала. Что я не делаю, чтобы эта работа работала? Может ли это быть связано с оператором list()?

Любая помощь приветствуется, чтобы сократить агонию ...

РЕДАКТИРОВАТЬ 2 - Решено, благодаря предложению Вуди. Это заняло много времени, но, в конце концов, я получил конкретный результат, который искал после того, как проверил формулу, данную Вуди. Существует несколько сценариев «Один канал для n элементов», но мне нужен был канал «n» для элементов n - это идеально и гибко. С моим нынешним уровнем опыта, чтобы найти такой ответ, потребовалось бы много времени - еще раз спасибо.

(some db_connect stuff..)

$query = "SELECT * 
      FROM webref_rss_items, webref_rss_details 
      WHERE webref_rss_details.id = webref_rss_items.chan_id 
      ORDER BY webref_rss_details.id";

$t_result = mysql_query( $query ) OR die ('Could not execute query: ' . mysql_error());
$rowCount = mysql_num_rows( $t_result );
$cat = -1;  // last category
for($r = 0; $r < $rowCount; $r++)
{
        $row = mysql_fetch_array( $t_result );
        if($row['id'] != $cat)
        {
            $cat = $row['id'];

        //create doctype
        $doc = new DOMDocument('1.0','UTF-8');
        header('content-type: text/xml');

        //create rss root with values
        $root = $doc->createElement('rss');
        $root->setAttribute('version', '2.0');
        $doc->appendChild($root);

        //create channel element
        $channel = $doc->createElement("channel");
        $root->appendChild($channel);

        // add node for each record, create the text nodes for element and add text
        $title = $doc->createElement('title', $row['title']);
        $channel->appendChild($title);

        $link = $doc->createElement('link', $row['link']);
        $channel->appendChild($link);

        $desc = $doc->createElement('description', $row['description']);
        $channel->appendChild($desc);

        $lang = $doc->createElement('language', $row['lang']);
        $channel->appendChild($lang);

        $image = $doc->createElement('image');
        $image = $channel->appendChild($image);

            $imttl = $doc->createElement('title', $row['image_title']);
            $image->appendChild($imttl);

            $imlink = $doc->createElement('link', $row['image_link']);
            $image->appendChild($imlink);

            $imdesc = $doc->createElement('description', $row['image_desc']);
            $image->appendChild($imdesc);

            $imwidth = $doc->createElement('width', $row['image_width']);
            $image->appendChild($imwidth);

            $imheight = $doc->createElement('height', $row['image_height']);
            $image->appendChild($imheight);

            $imurl = $doc->createElement('url', $row['image_url']);
            $image->appendChild($imurl);

        $manEdit = $doc->createElement('managingEditor', $row['man_edit']);
        $channel->appendChild($manEdit);

        $webmaster = $doc->createElement('webmaster', $row['webmaster']);
        $channel->appendChild($webmaster);

        $copyright = $doc->createElement('copyright', $row['copyright']);
        $channel->appendChild($copyright);

        $pubDate = $doc->createElement('pubDate', $row['ch_pubDate']);
        $channel->appendChild($pubDate);

        $lastBuild = $doc->createElement('lastBuildDate', $row['lastBuild']);
        $channel->appendChild($lastBuild);

        $category = $doc->createElement('category', $row['category']);
        $channel->appendChild($category);

        $generator = $doc->createElement('generator', $row['generator']);
        $channel->appendChild($generator);

        $docs = $doc->createElement('docs', $row['docs']);
        $channel->appendChild($docs);

        $cloud = $doc->createElement('cloud', $row['cloud']);
        $channel->appendChild($cloud);

        $ttl = $doc->createElement('ttl', $row['ttl']);
        $channel->appendChild($ttl);

        $rating = $doc->createElement('rating', $row['rating']);
        $channel->appendChild($rating);

        $textInput = $doc->createElement('textInput', $row['textInput']);
        $channel->appendChild($textInput);

        $skipHours = $doc->createElement('skipHours', $row['skipHours']);
        $channel->appendChild($skipHours);

        $skipDays = $doc->createElement('skipDays', $row['skipDays']);
        $channel->appendChild($skipDays);

            }

    //Dynamically Generated Items
    $item = $doc->createElement('item');
    $item = $channel->appendChild($item);

        $it_ttl = $doc->createElement('title', $line['title']);
        $item->appendChild($it_ttl);

        $it_desc = $doc->createElement('description', $line['desc']);
        $item->appendChild($it_desc);

        $it_link = $doc->createElement('link, $line['link']');
        $item->appendChild($it_link);

        $it_guid = $doc->createElement('guid', $line['guid']);
        $item->appendChild($it_guid);

        $it_pubDt = $doc->createElement('pubDate', $line['pubDate']);
        $item->appendChild($it_pubDt);

        $it_auth = $doc->createElement('author', $line['author']);
        $item->appendChild($it_auth);

        $it_ctg = $doc->createElement('category', $line['category']);
        $item->appendChild($it_ctg);

        $it_cmnt = $doc->createElement('comments', $line['comments']);
        $item->appendChild($it_cmnt);

        $it_encl = $doc->createElement('enclosure', $line['enclosure']);
        $item->appendChild($it_encl);

        $it_src = $doc->createElement('source', $line['source']);
        $item->appendChild($it_src);



    $mast  = $row['ch_title'];
$saw = explode(" ", $mast);
$chip =  $saw[0].'-'.$saw[1]; // saw1-saw2
$beam = "../../feed/".$chip.".xml";
echo 'Wrote: ' . $doc->save($beam) . '  bytes. <br /><br />';  
}   

}
?>

Отлично работает!

1 Ответ

0 голосов
/ 25 октября 2011

Лично я бы просто пошел в качестве простого запроса, такого как

select Channel.Title, Channel.Desc, Channel.Link, Channel.id, Item.Title, Item.Desc,
Item.Link as ItemLink from Item, Channel where Channel.id = Item.Chan_id 
order by Channel.id;

, получить все элементы (как мы говорим о небольшом количестве элементов), а затем перебрать их.Если channel.id не совпадает с предыдущим идентификатором канала, сделайте заголовок.

Я понятия не имею, что вы делаете с этими sprintfs, так как вы ничего не выполняете, они просто текстовыестроки, которые вы можете поместить прямо в запросы.

Я бы использовал классы для работы с базой данных не потому, что в этом примере она вам нужна, но это хорошая практика, и как только вы к ней привыкнете, она станет второй натурой.однако, в качестве примера (и не обязательно, как я бы это сделал):

    $query = "select Channel.Title as ChanTitle, Channel.Desc as ChanDesc, Channel.Link, Channel.id, Item.Title, Item.Desc, Item.Link as ItemLink from Item, Channel where Channel.id = Item.Chan_id order by Channel.id";

    $t_result = mysql_query( $query ) OR die ('Could not execute query: ' . mysql_error());
    $rowCount = mysql_num_rows( $t_result );
    $cat = -1;  // last category
    for($r = 0; $r < $rowCount; $r++)
    {
        $row = mysql_fetch_array( $t_result );
        if($row['id'] != $cat)
        {
            $cat = $row['id'];
            print $row['ChanTitle']."<br>";
            print $row['ChanDesc']."<br><br>";
        }
        print $row['Title']."<br>".$row['Desc']."<br><br>";
    }

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...