2013-08-19 16 views
6

Im Moment habe ich eine SQL und PHP-Problem, wo ich diese Anweisung verwenden alles von Dienstleistungen zu erhalten sowie die zugehörigen Tabellen:MySQL comma separated values ​​

$db = $this->getDbo(); 
$query = $db->getQuery(true); 

// Select the required fields from the table. 
$query->select(
     $this->getState(
       'list.select', 'a.*' 
     ) 
); 

$query->from('`#__services_service` AS a'); 
$query->where("a.zone"); 

$query->select('zone.name AS zone, zone.description AS zone_description, zone.price AS zone_price, zone.interval_recommended AS interval_recommended'); 
$query->join('LEFT', '#__services_zones AS zone ON zone.id = a.zone'); 

$query->select('category.icon AS category'); 
$query->join('LEFT', '#__services_categories AS category ON category.id = a.category'); 

Aber in der Zonentabelle I kommen, gibt es Komma getrennte Werte '1,2' und nach dem Erstellen eines assoziativen Arrays, wo ich die Dienste zu ihren Zonen gruppieren ein einzelner Service geht nur in eine singuläre Zone, anstatt, wenn der Wert in der Tabelle '1,2' ist, sollte es in beiden sein Zonen ... Ich habe das Gefühl, es ist wegen 'zone.name AS zone', denn dann gibt es nur einen Namen zurück und wenn ich sage 'zone AS zone' gibt es Komma getrennte Zahlen ...

Hier ist, wie ich das Array sortieren:

foreach($this->items as $item){ 
if(!isset($zones[ $item->zone ])) 
$zone_items[ $item->zone] = array(); 
$zone_items[ $item->zone ][] = $item; 

    $zones[$item->zone] = array(
     'zone' => $item->zone, 
     'zone_interval' => $item->interval_recommended, 
     'zone_description' => $item->zone_description, 
     'zone_price' => $item->zone_price, 
     'items' => $zone_items[$item->zone] 
    ); 

} 

und ich zeige es durch:

<?php foreach($zones as $zone): ?> 
    <div class="row-fluid zones-page"> 
     <div class="row-fluid zone-title-block"> 
      <div class="span4 zone-name"><h1><?php echo $zone['zone']; ?></h1></div> 
      <div class="span7 zone-description"> 
       <?php echo $zone['zone_description']; ?> 
       <?php if($zone['zone_interval'] == 1): ?> 
        <span class="interval pull-right">Interval Recommended</span> 
       <?php endif; ?> 
      </div> 
     </div> 

     <?php foreach($zone['items'] as $items) :?> 
     <div class="row-fluid zone-services-contain"> 
      <div class="span1"><div class="zone-icon"><?php //echo $items->category; ?></div></div> 
      <div class="span11 zone-services"> 
       <h4><?php echo $items->name; ?></h4> 
       <div><?php echo $items->description; ?></div> 
      </div> 
     </div> 
     <?php endforeach; ?> 

     <div class="row-fluid zone-amount"> 
      only <div><?php echo 'R' . $zone['zone_price']; ?></div> 
     </div> 
    </div> 
    <div class="bicycle-divider"> 
     <div class="bicycle-icon"></div> 
    </div> 
<?php endforeach; ?> 

Jede Hilfe wird sehr geschätzt.

Die Services Tabelle wie folgt aussieht:

enter image description here

Und die Zones Tabelle:

enter image description here

+0

Wie sieht die Tabelle aus? –

+0

welche? .. die Dienste, Zonen oder Kategorien? –

+0

Die Zonentabelle. –

Antwort

8

Aus diesem Grund ist in der Regel Menschen Link-Tabellen verwenden, um mit many-to-many-Beziehungen zu tun so was. Ein Dienst kann mehrere Zonen haben, eine Zone kann mehrere Dienste haben. Ein kommagetrenntes Feld abzufragen und es in einem Join mit einer anderen Tabelle zu verwenden, ist ziemlich schwierig.

Sie haben zwei Möglichkeiten, von denen eine die richtige Art und Weise zu tun hat, und eine erlaubt Ihnen, Ihr aktuelles Datenbankmodell zu behalten. Ich schlage vor, dass Sie es richtig machen, aber um Ihre Frage zu beantworten, gehe ich zuerst auf die andere Option ein.

Trennen Sie einfach Ihre Abfragen. Gerade das Komma getrennt Feld in der Hauptabfrage erhalten, dann eine zweite Abfrage ausführen, um die Zonennamen zu erhalten:

SELECT * FROM zone WHERE id IN ($zoneIdsYouSelected) 

Nun, wenn Sie mit einer Liste arbeiten, ist dies wahrscheinlich nicht sehr performant, weil es bedeutet, dass Sie Ich muss eine Abfrage für die Liste und eine weitere für jede Zeile ausführen. Eine Alternative wäre, alle Zonen in ein Array zu bringen und dann unter Verwendung von PHP basierend auf dem $zoneIdsYouSelected davon auszuwählen. Auf diese Weise können Sie mit zwei Abfragen fortfahren, anstatt mit einer Abfrage pro Datenzeile.

Der richtige Weg beinhaltet die Erstellung einer Verknüpfungstabelle, die einfach zwei Felder enthält: zone_id und service_id. Wenn Sie dann eine Abfrage wie diese machen, werden Sie alle Namen in einem „Feld“ in der Ergebnismenge erhalten:

SELECT s.id, s.name, s.description, s.price, s.category, s.ordering, 
     s.state, s.checked_out, s.checked_out_time, s.created_by, 
     GROUP_CONCAT(DISTINCT z.name ORDER BY z.name ASC SEPARATOR ', ') AS zones 
FROM  service s JOIN service_zone sz ON s.id = sz.service_id 
     JOIN zone z ON z.id = sz.zone_id 
GROUP BY s.id, s.name, s.description, s.price, s.category, s.ordering, 
     s.state, s.checked_out, s.checked_out_time, s.created_by 
ORDER BY s.id 

Sie werden wahrscheinlich die Abfrage ein wenig zwicken, aber ich hoffe, dass es klar ist. Denken Sie daran, dass GROUP_CONCAT nicht von allen Datenbanken unterstützt wird, sondern von MySQL.

Auch hier können beide Lösungen gut funktionieren und leistungsfähig sein, aber ein durch Komma getrenntes Feld wird mehr Probleme verursachen, genau wie dieses. Ich schlage vor, dass Sie Ihre Datenbankstruktur ändern. Informieren Sie sich über die Datenbanknormalisierung, wenn Sie nicht mit der Idee von Linktabellen vertraut sind.

+0

Wow danke !, nie daran gedacht, Tische zu verbinden ... Hey, mach es natürlich richtig !, was ist der Punkt, etwas zu tun und zu wissen, was falsch ist? vielen dank ... krank versuchen es wirklich schnell: D –

Verwandte Themen